GCC Code Coverage Report


Directory: ./
File: sql/sql_optimizer.cc
Date: 2022-12-06 21:40:42
Exec Total Coverage
Lines: 4219 4409 95.7%
Branches: 5370 7293 73.6%

Line Branch Exec Source
1 /* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 /**
24 @file
25
26 @brief Optimize query expressions: Make optimal table join order, select
27 optimal access methods per table, apply grouping, sorting and
28 limit processing.
29
30 @defgroup Query_Optimizer Query Optimizer
31 @{
32 */
33
34 #include "sql/sql_optimizer.h"
35 #include "sql/sql_optimizer_internal.h"
36
37 #include <limits.h>
38 #include <algorithm>
39 #include <atomic>
40 #include <deque>
41 #include <new>
42 #include <string>
43 #include <utility>
44 #include <vector>
45
46 #include "field_types.h" // enum_field_types
47 #include "ft_global.h"
48 #include "m_ctype.h"
49 #include "mem_root_deque.h"
50 #include "memory_debugging.h"
51 #include "my_bit.h" // my_count_bits
52 #include "my_bitmap.h"
53 #include "my_compiler.h"
54 #include "my_dbug.h"
55 #include "my_inttypes.h"
56 #include "my_sqlcommand.h"
57 #include "my_sys.h"
58 #include "mysql/udf_registration_types.h"
59 #include "mysql_com.h"
60 #include "mysqld_error.h"
61 #include "sql/check_stack.h"
62 #include "sql/current_thd.h"
63 #include "sql/debug_sync.h" // DEBUG_SYNC
64 #include "sql/derror.h" // ER_THD
65 #include "sql/enum_query_type.h"
66 #include "sql/error_handler.h" // Functional_index_error_handler
67 #include "sql/handler.h"
68 #include "sql/item.h"
69 #include "sql/item_cmpfunc.h"
70 #include "sql/item_func.h"
71 #include "sql/item_row.h"
72 #include "sql/item_subselect.h"
73 #include "sql/item_sum.h" // Item_sum
74 #include "sql/iterators/basic_row_iterators.h"
75 #include "sql/iterators/timing_iterator.h"
76 #include "sql/join_optimizer/access_path.h"
77 #include "sql/join_optimizer/join_optimizer.h"
78 #include "sql/key.h"
79 #include "sql/key_spec.h"
80 #include "sql/lock.h" // mysql_unlock_some_tables
81 #include "sql/mysqld.h" // stage_optimizing
82 #include "sql/nested_join.h"
83 #include "sql/opt_costmodel.h"
84 #include "sql/opt_explain.h" // join_type_str
85 #include "sql/opt_hints.h" // hint_table_state
86 #include "sql/opt_trace.h" // Opt_trace_object
87 #include "sql/opt_trace_context.h"
88 #include "sql/parse_tree_node_base.h"
89 #include "sql/parser_yystype.h"
90 #include "sql/query_options.h"
91 #include "sql/query_result.h"
92 #include "sql/range_optimizer/partition_pruning.h"
93 #include "sql/range_optimizer/path_helpers.h"
94 #include "sql/range_optimizer/range_optimizer.h"
95 #include "sql/sql_base.h" // init_ftfuncs
96 #include "sql/sql_bitmap.h"
97 #include "sql/sql_class.h"
98 #include "sql/sql_const.h"
99 #include "sql/sql_const_folding.h"
100 #include "sql/sql_error.h"
101 #include "sql/sql_join_buffer.h" // JOIN_CACHE
102 #include "sql/sql_planner.h" // calculate_condition_filter
103 #include "sql/sql_test.h" // print_where
104 #include "sql/sql_tmp_table.h"
105 #include "sql/system_variables.h"
106 #include "sql/table.h"
107 #include "sql/thd_raii.h"
108 #include "sql/window.h"
109 #include "sql_string.h"
110 #include "template_utils.h"
111
112 using std::max;
113 using std::min;
114
115 const char *antijoin_null_cond = "<ANTIJOIN-NULL>";
116
117 static bool optimize_semijoin_nests_for_materialization(JOIN *join);
118 static void calculate_materialization_costs(JOIN *join, TABLE_LIST *sj_nest,
119 uint n_tables,
120 Semijoin_mat_optimize *sjm);
121 static bool make_join_query_block(JOIN *join, Item *item);
122 static bool list_contains_unique_index(JOIN_TAB *tab,
123 bool (*find_func)(Field *, void *),
124 void *data);
125 static bool find_field_in_item_list(Field *field, void *data);
126 static bool find_field_in_order_list(Field *field, void *data);
127 static TABLE *get_sort_by_table(ORDER *a, ORDER *b, TABLE_LIST *tables);
128 static void trace_table_dependencies(Opt_trace_context *trace,
129 JOIN_TAB *join_tabs, uint table_count);
130 static bool update_ref_and_keys(THD *thd, Key_use_array *keyuse,
131 JOIN_TAB *join_tab, uint tables, Item *cond,
132 table_map normal_tables,
133 Query_block *query_block,
134 SARGABLE_PARAM **sargables);
135 static bool pull_out_semijoin_tables(JOIN *join);
136 static void add_loose_index_scan_and_skip_scan_keys(JOIN *join,
137 JOIN_TAB *join_tab);
138 static ha_rows get_quick_record_count(THD *thd, JOIN_TAB *tab, ha_rows limit);
139 static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables,
140 table_map *cached_eq_ref_tables,
141 table_map *eq_ref_tables);
142 static bool setup_join_buffering(JOIN_TAB *tab, JOIN *join, uint no_jbuf_after);
143
144 static bool test_if_skip_sort_order(JOIN_TAB *tab, ORDER_with_src &order,
145 ha_rows select_limit, const bool no_changes,
146 const Key_map *map, int *best_idx);
147
148 static Item_func_match *test_if_ft_index_order(ORDER *order);
149
150 static uint32 get_key_length_tmp_table(Item *item);
151 static bool can_switch_from_ref_to_range(THD *thd, JOIN_TAB *tab,
152 enum_order ordering,
153 bool recheck_range);
154
155 static bool has_not_null_predicate(Item *cond, Item_field *not_null_item);
156
157 9987004 JOIN::JOIN(THD *thd_arg, Query_block *select)
158 9987004 : query_block(select),
159 9987004 thd(thd_arg),
160 // @todo Can this be substituted with select->is_explicitly_grouped()?
161 19974036 grouped(select->is_explicitly_grouped()),
162 // Inner tables may always be considered to be constant:
163 9987013 const_table_map(INNER_TABLE_BIT),
164 9987013 found_const_table_map(INNER_TABLE_BIT),
165 // Needed in case optimizer short-cuts, set properly in
166 // make_tmp_tables_info()
167 9987013 fields(&select->fields),
168 9987029 tmp_table_param(thd_arg->mem_root),
169 9987011 lock(thd->lock),
170 // @todo Can this be substituted with select->is_implicitly_grouped()?
171 9987011 implicit_grouping(select->is_implicitly_grouped()),
172 9987018 select_distinct(select->is_distinct()),
173 9987026 keyuse_array(thd->mem_root),
174 9987010 order(select->order_list.first, ESC_ORDER_BY),
175 9987011 group_list(select->group_list.first, ESC_GROUP_BY),
176 9987012 m_windows(select->m_windows),
177 /*
178 Those four members are meaningless before JOIN::optimize(), so force a
179 crash if they are used before that.
180 */
181 9987010 where_cond(reinterpret_cast<Item *>(1)),
182 9987010 having_cond(reinterpret_cast<Item *>(1)),
183 9987010 having_for_explain(reinterpret_cast<Item *>(1)),
184 9987010 tables_list(reinterpret_cast<TABLE_LIST *>(1)),
185 9987010 current_ref_item_slice(REF_SLICE_SAVED_BASE),
186
2/4
✓ Branch 0 taken 9987011 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9987010 times.
✗ Branch 3 not taken.
39948069 with_json_agg(select->json_agg_func_used()) {
187 9987018 rollup_state = RollupState::NONE;
188
2/2
✓ Branch 0 taken 641075 times.
✓ Branch 1 taken 9345943 times.
9987018 if (select->order_list.first) explain_flags.set(ESC_ORDER_BY, ESP_EXISTS);
189
2/2
✓ Branch 0 taken 10533 times.
✓ Branch 1 taken 9976484 times.
9987017 if (select->group_list.first) explain_flags.set(ESC_GROUP_BY, ESP_EXISTS);
190
2/2
✓ Branch 0 taken 4046 times.
✓ Branch 1 taken 9982980 times.
9987017 if (select->is_distinct()) explain_flags.set(ESC_DISTINCT, ESP_EXISTS);
191
2/2
✓ Branch 0 taken 1523 times.
✓ Branch 1 taken 9985503 times.
9987026 if (m_windows.elements > 0) explain_flags.set(ESC_WINDOWING, ESP_EXISTS);
192 // Calculate the number of groups
193
2/2
✓ Branch 0 taken 18341 times.
✓ Branch 1 taken 9987023 times.
10005364 for (ORDER *group = group_list.order; group; group = group->next)
194 18341 send_group_parts++;
195 9987023 }
196
197 580744 bool JOIN::alloc_ref_item_slice(THD *thd_arg, int sliceno) {
198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 580744 times.
580744 assert(sliceno > 0);
199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 580744 times.
580744 assert(ref_items[sliceno].is_null());
200 580744 size_t count = ref_items[0].size();
201 580743 Item **slice = thd_arg->mem_root->ArrayAlloc<Item *>(count);
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 580744 times.
580744 if (slice == nullptr) return true;
203 580744 ref_items[sliceno] = Ref_item_array(slice, count);
204 580744 return false;
205 }
206
207 9923718 bool JOIN::alloc_indirection_slices() {
208 9923718 const int num_slices = REF_SLICE_WIN_1 + m_windows.elements;
209
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9923718 times.
9923718 assert(ref_items == nullptr);
211 9923718 ref_items = (*THR_MALLOC)->ArrayAlloc<Ref_item_array>(num_slices);
212
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9923737 times.
9923737 if (ref_items == nullptr) return true;
213
214 9923738 tmp_fields =
215 9923737 (*THR_MALLOC)
216 9923742 ->ArrayAlloc<mem_root_deque<Item *>>(num_slices, *THR_MALLOC);
217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9923738 times.
9923738 if (tmp_fields == nullptr) return true;
218
219 9923738 return false;
220 }
221
222 /**
223 The List<Item_equal> in COND_EQUAL partially overlaps with the argument list
224 in various Item_cond via C-style casts. However, the hypergraph optimizer can
225 modify the lists in Item_cond (by calling compile()), causing an Item_equal to
226 be replaced with Item_func_eq, and this can cause a List<Item_equal> not to
227 contain Item_equal pointers anymore. This is is obviously bad if anybody wants
228 to actually look into these lists after optimization (in particular, NDB
229 wants this).
230
231 Since untangling this spaghetti seems very hard, we solve it by brute force:
232 Make a copy of all the COND_EQUAL lists, so that they no longer reach into the
233 Item_cond. This allows us to modify the Item_cond at will.
234 */
235 53 static void SaveCondEqualLists(COND_EQUAL *cond_equal) {
236
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 7 times.
53 if (cond_equal == nullptr) {
237 46 return;
238 }
239 7 List<Item_equal> copy;
240
5/8
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 7 times.
12 for (Item_equal &item : cond_equal->current_level) {
241
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 copy.push_back(&item);
242 }
243 7 cond_equal->current_level = std::move(copy);
244
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 SaveCondEqualLists(cond_equal->upper_levels);
245 }
246
247 /**
248 Optimizes one query block into a query execution plan (QEP.)
249
250 This is the entry point to the query optimization phase. This phase
251 applies both logical (equivalent) query rewrites, cost-based join
252 optimization, and rule-based access path selection. Once an optimal
253 plan is found, the member function creates/initializes all
254 structures needed for query execution. The main optimization phases
255 are outlined below:
256
257 -# Logical transformations:
258 - Outer to inner joins transformation.
259 - Equality/constant propagation.
260 - Partition pruning.
261 - COUNT(*), MIN(), MAX() constant substitution in case of
262 implicit grouping.
263 - ORDER BY optimization.
264 -# Perform cost-based optimization of table order and access path
265 selection. See JOIN::make_join_plan()
266 -# Post-join order optimization:
267 - Create optimal table conditions from the where clause and the
268 join conditions.
269 - Inject outer-join guarding conditions.
270 - Adjust data access methods after determining table condition
271 (several times.)
272 - Optimize ORDER BY/DISTINCT.
273 -# Code generation
274 - Set data access functions.
275 - Try to optimize away sorting/distinct.
276 - Setup temporary table usage for grouping and/or sorting.
277
278 @retval false Success.
279 @retval true Error, error code saved in member JOIN::error.
280 */
281 9923734 bool JOIN::optimize(bool finalize_access_paths) {
282
1/2
✓ Branch 0 taken 9923749 times.
✗ Branch 1 not taken.
9923734 DBUG_TRACE;
283
284 9923749 uint no_jbuf_after = UINT_MAX;
285
286
5/6
✓ Branch 0 taken 1930025 times.
✓ Branch 1 taken 7993724 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1930024 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
9923749 assert(query_block->leaf_table_count == 0 ||
287 thd->lex->is_query_tables_locked() ||
288 query_block == query_expression()->fake_query_block);
289
4/6
✓ Branch 0 taken 9923741 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 9923742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9923744 times.
✗ Branch 5 not taken.
9923749 assert(tables == 0 && primary_tables == 0 && tables_list == (TABLE_LIST *)1);
290
291 // to prevent double initialization on EXPLAIN
292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9923744 times.
9923744 if (optimized) return false;
293
294
3/4
✓ Branch 0 taken 9900279 times.
✓ Branch 1 taken 23462 times.
✓ Branch 2 taken 9900287 times.
✗ Branch 3 not taken.
9923744 DEBUG_SYNC(thd, "before_join_optimize");
295
296
1/2
✓ Branch 0 taken 9923743 times.
✗ Branch 1 not taken.
9923749 THD_STAGE_INFO(thd, stage_optimizing);
297
298 9923743 Opt_trace_context *const trace = &thd->opt_trace;
299
1/2
✓ Branch 0 taken 9923747 times.
✗ Branch 1 not taken.
9923743 Opt_trace_object trace_wrapper(trace);
300
1/2
✓ Branch 0 taken 9923748 times.
✗ Branch 1 not taken.
9923747 Opt_trace_object trace_optimize(trace, "join_optimization");
301
1/2
✓ Branch 0 taken 9923748 times.
✗ Branch 1 not taken.
9923748 trace_optimize.add_select_number(query_block->select_number);
302
1/2
✓ Branch 0 taken 9923740 times.
✗ Branch 1 not taken.
9923748 Opt_trace_array trace_steps(trace, "steps");
303
304
1/2
✓ Branch 0 taken 9923749 times.
✗ Branch 1 not taken.
9923740 count_field_types(query_block, &tmp_table_param, *fields, false, false);
305
306
5/6
✓ Branch 0 taken 440034 times.
✓ Branch 1 taken 9483715 times.
✓ Branch 2 taken 431563 times.
✓ Branch 3 taken 8471 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 431563 times.
9923749 assert(tmp_table_param.sum_func_count == 0 || !group_list.empty() ||
307 implicit_grouping);
308
309 9923749 const bool has_windows = m_windows.elements != 0;
310
311
7/8
✓ Branch 0 taken 1523 times.
✓ Branch 1 taken 9922226 times.
✓ Branch 2 taken 1523 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1518 times.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 9923744 times.
9923749 if (has_windows && Window::setup_windows2(thd, &m_windows))
312 5 return true; /* purecov: inspected */
313
314
5/8
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 9923410 times.
✓ Branch 2 taken 334 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 334 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 9923744 times.
9923744 if (query_block->olap == ROLLUP_TYPE && optimize_rollup())
315 return true; /* purecov: inspected */
316
317
2/4
✓ Branch 0 taken 9923730 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9923730 times.
9923744 if (alloc_func_list()) return true; /* purecov: inspected */
318
319
2/4
✓ Branch 0 taken 9923740 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9923740 times.
9923730 if (query_block->get_optimizable_conditions(thd, &where_cond, &having_cond))
320 return true;
321
322
4/6
✓ Branch 0 taken 9923723 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9923735 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 920 times.
✓ Branch 5 taken 9923735 times.
9924660 for (Item_rollup_group_item *item : query_block->rollup_group_items) {
323
1/2
✓ Branch 0 taken 920 times.
✗ Branch 1 not taken.
920 rollup_group_items.push_back(item);
324 }
325
4/6
✓ Branch 0 taken 9923738 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9923739 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 315 times.
✓ Branch 5 taken 9923739 times.
9924050 for (Item_rollup_sum_switcher *item : query_block->rollup_sums) {
326
1/2
✓ Branch 0 taken 315 times.
✗ Branch 1 not taken.
315 rollup_sums.push_back(item);
327 }
328
329 9923739 set_optimized();
330
331 9923723 tables_list = query_block->leaf_tables;
332
333
2/4
✓ Branch 0 taken 9923739 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9923739 times.
9923723 if (alloc_indirection_slices()) return true;
334
335 // The base ref items from query block are assigned as JOIN's ref items
336 9923739 ref_items[REF_SLICE_ACTIVE] = query_block->base_ref_items;
337
338 /* dump_TABLE_LIST_graph(query_block, query_block->leaf_tables); */
339 /*
340 Run optimize phase for all derived tables/views used in this SELECT,
341 including those in semi-joins.
342 */
343 // if (query_block->materialized_derived_table_count) {
344 { // WL#6570
345
2/2
✓ Branch 0 taken 3947930 times.
✓ Branch 1 taken 9923734 times.
13871664 for (TABLE_LIST *tl = query_block->leaf_tables; tl; tl = tl->next_leaf) {
346 3947930 tl->access_path_for_derived = nullptr;
347
2/2
✓ Branch 0 taken 145791 times.
✓ Branch 1 taken 3802141 times.
3947930 if (tl->is_view_or_derived()) {
348
3/4
✓ Branch 0 taken 145792 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 145776 times.
145791 if (tl->optimize_derived(thd)) return true;
349
2/2
✓ Branch 0 taken 601 times.
✓ Branch 1 taken 3801546 times.
3802141 } else if (tl->is_table_function()) {
350 601 TABLE *const table = tl->table;
351
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 573 times.
601 if (!table->has_storage_handler()) {
352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (setup_tmp_table_handler(
353
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 thd, table,
354 30 query_block->active_options() | TMP_TABLE_ALL_COLUMNS))
355 return true; /* purecov: inspected */
356 }
357
358 603 table->file->stats.records = 2;
359 }
360 }
361 }
362
363
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 9923683 times.
9923734 if (thd->lex->using_hypergraph_optimizer) {
364 // The hypergraph optimizer also wants all subselect items to be optimized,
365 // so that it has cost information to attach to filter nodes.
366 51 for (Query_expression *unit = query_block->first_inner_query_expression();
367
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 51 times.
58 unit; unit = unit->next_query_expression()) {
368 // Derived tables and const subqueries are already optimized
369
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
14 if (!unit->is_optimized() &&
370
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 unit->optimize(thd, /*materialize_destination=*/nullptr,
371 /*create_iterators=*/false,
372 /*finalize_access_paths=*/false))
373 return true;
374 }
375
376 // The hypergraph optimizer does not do const tables,
377 // nor does it evaluate subqueries during optimization.
378 51 query_block->add_active_options(OPTION_NO_CONST_TABLES |
379 OPTION_NO_SUBQUERY_DURING_OPTIMIZATION);
380 }
381
382 9923713 has_lateral = false;
383
384 /* dump_TABLE_LIST_graph(query_block, query_block->leaf_tables); */
385
386
4/4
✓ Branch 0 taken 9280299 times.
✓ Branch 1 taken 639385 times.
✓ Branch 2 taken 9273389 times.
✓ Branch 3 taken 6922 times.
9919689 row_limit = ((select_distinct || !order.empty() || !group_list.empty())
387
2/2
✓ Branch 0 taken 9919689 times.
✓ Branch 1 taken 4024 times.
19843413 ? HA_POS_ERROR
388 9273389 : query_expression()->select_limit_cnt);
389 // m_select_limit is used to decide if we are likely to scan the whole table.
390 9923724 m_select_limit = query_expression()->select_limit_cnt;
391
392
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 9923546 times.
9923725 if (query_expression()->first_query_block()->active_options() &
393 OPTION_FOUND_ROWS) {
394 /*
395 Calculate found rows (ie., keep counting rows even after we hit LIMIT) if
396 - LIMIT is set, and
397 - This is the outermost query block (for a UNION query, this is the
398 fake query block that contains the limit applied on the final UNION
399 evaluation).
400 */
401
2/2
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 59 times.
301 calc_found_rows = m_select_limit != HA_POS_ERROR &&
402
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 95 times.
121 (!query_expression()->is_union() ||
403
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 14 times.
26 query_block == query_expression()->fake_query_block);
404 }
405
4/4
✓ Branch 0 taken 9919740 times.
✓ Branch 1 taken 3986 times.
✓ Branch 2 taken 107 times.
✓ Branch 3 taken 9919633 times.
9923726 if (having_cond || calc_found_rows) m_select_limit = HA_POS_ERROR;
406
407
6/6
✓ Branch 0 taken 231 times.
✓ Branch 1 taken 9923491 times.
✓ Branch 2 taken 213 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 213 times.
✓ Branch 5 taken 9923509 times.
9923726 if (query_expression()->select_limit_cnt == 0 && !calc_found_rows) {
408 213 zero_result_cause = "Zero limit";
409 213 best_rowcount = 0;
410
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 create_access_paths_for_zero_rows();
411 213 goto setup_subq_exit;
412 }
413
414
4/4
✓ Branch 0 taken 8599456 times.
✓ Branch 1 taken 1324053 times.
✓ Branch 2 taken 3963 times.
✓ Branch 3 taken 8595493 times.
9923509 if (where_cond || query_block->outer_join) {
415
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1327988 times.
1327998 if (optimize_cond(thd, &where_cond, &cond_equal,
416
1/2
✓ Branch 0 taken 1327998 times.
✗ Branch 1 not taken.
1328016 &query_block->top_join_list, &query_block->cond_value)) {
417 10 error = 1;
418
3/8
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
10 DBUG_PRINT("error", ("Error from optimize_cond"));
419 10 return true;
420 }
421
2/2
✓ Branch 0 taken 8197 times.
✓ Branch 1 taken 1319791 times.
1327988 if (query_block->cond_value == Item::COND_FALSE) {
422 8197 zero_result_cause = "Impossible WHERE";
423 8197 best_rowcount = 0;
424
1/2
✓ Branch 0 taken 8197 times.
✗ Branch 1 not taken.
8197 create_access_paths_for_zero_rows();
425 8197 goto setup_subq_exit;
426 }
427 }
428
2/2
✓ Branch 0 taken 3968 times.
✓ Branch 1 taken 9911316 times.
9915284 if (having_cond) {
429
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3966 times.
3968 if (optimize_cond(thd, &having_cond, &cond_equal, nullptr,
430
1/2
✓ Branch 0 taken 3968 times.
✗ Branch 1 not taken.
3968 &query_block->having_value)) {
431 2 error = 1;
432
3/8
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2 DBUG_PRINT("error", ("Error from optimize_cond"));
433 2 return true;
434 }
435
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 3924 times.
3966 if (query_block->having_value == Item::COND_FALSE) {
436 42 zero_result_cause = "Impossible HAVING";
437 42 best_rowcount = 0;
438
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 create_access_paths_for_zero_rows();
439 42 goto setup_subq_exit;
440 }
441 }
442
443
2/2
✓ Branch 0 taken 9886191 times.
✓ Branch 1 taken 29049 times.
9915240 if (thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
444
2/2
✓ Branch 0 taken 554 times.
✓ Branch 1 taken 9885637 times.
9886191 thd->lex->sql_command == SQLCOM_REPLACE_SELECT) {
445 /*
446 Statement-based replication of INSERT ... SELECT ... LIMIT and
447 REPLACE ... SELECT is safe as order of row is defined with either
448 ORDER BY or other condition. However it is too late for it have
449 an impact to our decision to switch to row- based. We can only
450 suppress warning here.
451 */
452
1/2
✓ Branch 0 taken 682 times.
✗ Branch 1 not taken.
682 if (query_block->select_limit && query_block->select_limit->fixed &&
453
6/8
✓ Branch 0 taken 682 times.
✓ Branch 1 taken 28921 times.
✓ Branch 2 taken 682 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 682 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 413 times.
✓ Branch 7 taken 29190 times.
30967 query_block->select_limit->val_int() &&
454
3/4
✓ Branch 0 taken 682 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 413 times.
✓ Branch 3 taken 269 times.
682 !is_order_deterministic(&query_block->top_join_list, where_cond,
455 order.order)) {
456 413 thd->order_deterministic = false;
457 }
458 }
459
460
7/8
✓ Branch 0 taken 19627 times.
✓ Branch 1 taken 9895613 times.
✓ Branch 2 taken 19627 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 19624 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 9915237 times.
9915240 if (query_block->partitioned_table_count && prune_table_partitions()) {
461 3 error = 1;
462
3/8
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
3 DBUG_PRINT("error", ("Error from prune_partitions"));
463 3 return true;
464 }
465
466 /*
467 Try to optimize count(*), min() and max() to const fields if
468 there is implicit grouping (aggregate functions but no
469 group_list). In this case, the result set shall only contain one
470 row.
471 */
472
6/6
✓ Branch 0 taken 1921742 times.
✓ Branch 1 taken 7993495 times.
✓ Branch 2 taken 430134 times.
✓ Branch 3 taken 1491608 times.
✓ Branch 4 taken 430096 times.
✓ Branch 5 taken 9485141 times.
10345371 if (tables_list && implicit_grouping &&
473
2/2
✓ Branch 0 taken 430096 times.
✓ Branch 1 taken 38 times.
430134 !(query_block->active_options() & OPTION_NO_CONST_TABLES)) {
474 aggregate_evaluated outcome;
475
3/4
✓ Branch 0 taken 430096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 430093 times.
430096 if (optimize_aggregated_query(thd, query_block, *fields, where_cond,
476 &outcome)) {
477 3 error = 1;
478
3/8
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
3 DBUG_PRINT("error", ("Error from optimize_aggregated_query"));
479 3 return true;
480 }
481
4/5
✓ Branch 0 taken 405249 times.
✓ Branch 1 taken 15262 times.
✓ Branch 2 taken 5080 times.
✓ Branch 3 taken 4502 times.
✗ Branch 4 not taken.
430093 switch (outcome) {
482 405249 case AGGR_REGULAR:
483 // Query was not (fully) evaluated. Revert to regular optimization.
484 405249 break;
485 15262 case AGGR_DELAYED:
486 // Query was not (fully) evaluated. Revert to regular optimization,
487 // but indicate that storage engine supports HA_COUNT_ROWS_INSTANT.
488 15262 select_count = true;
489 15262 break;
490 5080 case AGGR_COMPLETE: {
491 // All SELECT expressions are fully evaluated
492
3/8
✓ Branch 0 taken 5080 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5080 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5080 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
5080 DBUG_PRINT("info", ("Select tables optimized away"));
493 5080 zero_result_cause = "Select tables optimized away";
494 5080 tables_list = nullptr; // All tables resolved
495 5080 best_rowcount = 1;
496 5080 const_tables = tables = primary_tables = query_block->leaf_table_count;
497 AccessPath *path =
498 5080 NewFakeSingleRowAccessPath(thd, /*count_examined_rows=*/true);
499
1/2
✓ Branch 0 taken 5080 times.
✗ Branch 1 not taken.
5080 path = attach_access_paths_for_having_and_limit(path);
500 5080 m_root_access_path = path;
501 /*
502 There are no relevant conditions left from the WHERE;
503 optimize_aggregated_query() will not return AGGR_COMPLETE if there are
504 any table-independent conditions, and all other conditions have been
505 optimized away by it. Thus, remove the condition, unless we have
506 EXPLAIN (in which case we will keep it for printing).
507 */
508
2/2
✓ Branch 0 taken 4986 times.
✓ Branch 1 taken 94 times.
5080 if (!thd->lex->is_explain()) {
509 #ifndef NDEBUG
510 // Verify, to be sure.
511
2/2
✓ Branch 0 taken 3250 times.
✓ Branch 1 taken 1736 times.
4986 if (where_cond != nullptr) {
512 6500 Item *table_independent_conds = make_cond_for_table(
513
1/2
✓ Branch 0 taken 3250 times.
✗ Branch 1 not taken.
3250 thd, where_cond, PSEUDO_TABLE_BITS, table_map(0),
514 /*exclude_expensive_cond=*/true);
515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3250 times.
3250 assert(table_independent_conds == nullptr);
516 }
517 #endif
518 4986 where_cond = nullptr;
519 }
520 9582 goto setup_subq_exit;
521 }
522 4502 case AGGR_EMPTY:
523 // It was detected that the result tables are empty
524
3/8
✓ Branch 0 taken 4502 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4502 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4502 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
4502 DBUG_PRINT("info", ("No matching min/max row"));
525 4502 zero_result_cause = "No matching min/max row";
526
1/2
✓ Branch 0 taken 4502 times.
✗ Branch 1 not taken.
4502 create_access_paths_for_zero_rows();
527 4502 goto setup_subq_exit;
528 }
529 }
530
2/2
✓ Branch 0 taken 7993494 times.
✓ Branch 1 taken 1912158 times.
9905652 if (tables_list == nullptr) {
531
5/8
✓ Branch 0 taken 7993499 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7993502 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 7993499 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
7993494 DBUG_PRINT("info", ("No tables"));
532 7993502 best_rowcount = 1;
533 7993502 error = 0;
534
3/4
✓ Branch 0 taken 7993503 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 7993502 times.
7993502 if (make_tmp_tables_info()) return true;
535
1/2
✓ Branch 0 taken 7993501 times.
✗ Branch 1 not taken.
7993502 count_field_types(query_block, &tmp_table_param, *fields, false, false);
536 // Make plan visible for EXPLAIN
537
1/2
✓ Branch 0 taken 7993503 times.
✗ Branch 1 not taken.
7993501 set_plan_state(NO_TABLES);
538
1/2
✓ Branch 0 taken 7993498 times.
✗ Branch 1 not taken.
7993503 create_access_paths();
539 7993498 return false;
540 }
541 1912158 error = -1; // Error is sent to client
542
543 {
544 1912158 m_windowing_steps = false; // initialization
545 1912158 m_windows_sort = false;
546
1/2
✓ Branch 0 taken 1912164 times.
✗ Branch 1 not taken.
1912158 List_iterator<Window> li(m_windows);
547 Window *w;
548
2/2
✓ Branch 0 taken 1365 times.
✓ Branch 1 taken 1911269 times.
1912630 while ((w = li++))
549
2/2
✓ Branch 0 taken 899 times.
✓ Branch 1 taken 466 times.
1365 if (w->needs_sorting()) {
550 899 m_windows_sort = true;
551 899 break;
552 }
553 }
554
555 3824331 sort_by_table = get_sort_by_table(order.order, group_list.order,
556
1/2
✓ Branch 0 taken 1912163 times.
✗ Branch 1 not taken.
1912168 query_block->leaf_tables);
557
558
8/8
✓ Branch 0 taken 606945 times.
✓ Branch 1 taken 1305218 times.
✓ Branch 2 taken 602636 times.
✓ Branch 3 taken 4309 times.
✓ Branch 4 taken 246046 times.
✓ Branch 5 taken 356591 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 1912167 times.
3467742 if ((where_cond || !group_list.empty() || !order.empty()) &&
559
3/4
✓ Branch 0 taken 1555579 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1555576 times.
1555573 substitute_gc(thd, query_block, where_cond, group_list.order,
560 order.order)) {
561 // We added hidden fields to the all_fields list, count them.
562
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 count_field_types(query_block, &tmp_table_param, query_block->fields, false,
563 false);
564 }
565 // Ensure there are no errors prior making query plan
566
3/4
✓ Branch 0 taken 1912173 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1912171 times.
1912170 if (thd->is_error()) return true;
567
568
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 1912125 times.
1912171 if (thd->lex->using_hypergraph_optimizer) {
569
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 Item *where_cond_no_in2exists = remove_in2exists_conds(thd, where_cond);
570
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 Item *having_cond_no_in2exists = remove_in2exists_conds(thd, having_cond);
571
572 46 std::string trace_str;
573
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 std::string *trace_ptr = thd->opt_trace.is_started() ? &trace_str : nullptr;
574
575
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 SaveCondEqualLists(cond_equal);
576
577
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 m_root_access_path = FindBestQueryPlan(thd, query_block, trace_ptr);
578
3/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
46 if (finalize_access_paths && m_root_access_path != nullptr) {
579
2/4
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39 times.
39 if (FinalizePlanForQueryBlock(thd, query_block)) {
580 return true;
581 }
582 }
583
584 // If this query block was modified by IN-to-EXISTS conversion,
585 // the outer query block may want to undo that conversion and materialize
586 // us instead, depending on cost. (Materialization has high initial cost,
587 // but looking up in the materialized table is typically cheaper than
588 // running the entire query.) If so, we will need to plan the query again,
589 // but with all extra conditions added by IN-to-EXISTS removed, as those
590 // are specific to the values referred to by the outer query.
591 //
592 // Thus, we detect this here, and plan a second query plan. There are
593 // computations that could be shared between the two plans (e.g. join order
594 // between tables for which there is no IN-to-EXISTS-related condition),
595 // so it is somewhat wasteful, but experiments have shown that planning
596 // both at the same time quickly clutters the code with such handling;
597 // there are so many places such filters could be added (base table filters,
598 // filters after various types of joins, join conditions, post-join filters,
599 // HAVING, possibly others) that trying to plan paths both with and without
600 // them incurs complexity that is not justified by the small computational
601 // gain it would bring.
602
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 if (where_cond != where_cond_no_in2exists ||
603
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 39 times.
46 having_cond != having_cond_no_in2exists) {
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (trace_ptr != nullptr) {
605 *trace_ptr +=
606 "\nPlanning an alternative with in2exists conditions removed:\n";
607 }
608 7 where_cond = where_cond_no_in2exists;
609 7 having_cond = having_cond_no_in2exists;
610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 assert(!finalize_access_paths);
611 7 m_root_access_path_no_in2exists =
612
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 FindBestQueryPlan(thd, query_block, trace_ptr);
613 } else {
614 39 m_root_access_path_no_in2exists = nullptr;
615 }
616
617
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 if (trace != nullptr) {
618
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 Opt_trace_object trace_wrapper2(&thd->opt_trace);
619
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 Opt_trace_array join_optimizer(&thd->opt_trace, "join_optimizer");
620
621 // Split by newlines.
622
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 for (size_t pos = 0; pos < trace_str.size();) {
623 size_t len = strcspn(trace_str.data() + pos, "\n");
624 join_optimizer.add_utf8(trace_str.data() + pos, len);
625 pos += len + 1;
626 }
627 46 }
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (m_root_access_path == nullptr) {
629 return true;
630 }
631
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 set_plan_state(PLAN_READY);
632
2/4
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46 times.
✗ Branch 3 not taken.
46 DEBUG_SYNC(thd, "after_join_optimize");
633 46 return false;
634 46 }
635
636 // ----------------------------------------------------------------------------
637 // All of this is never called for the hypergraph join optimizer!
638 // ----------------------------------------------------------------------------
639
640 // Set up join order and initial access paths
641
1/2
✓ Branch 0 taken 1912122 times.
✗ Branch 1 not taken.
1912125 THD_STAGE_INFO(thd, stage_statistics);
642
3/4
✓ Branch 0 taken 1912122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 126 times.
✓ Branch 3 taken 1911996 times.
1912122 if (make_join_plan()) {
643
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 109 times.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
126 if (thd->killed) thd->send_kill_message();
644
3/8
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 126 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 126 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
126 DBUG_PRINT("error", ("Error: JOIN::make_join_plan() failed"));
645 126 return true;
646 }
647
648 // At this stage, join_tab==NULL, JOIN_TABs are listed in order by best_ref.
649
4/6
✓ Branch 0 taken 1911982 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1911989 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1911991 times.
✗ Branch 5 not taken.
1911996 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
650
651
2/2
✓ Branch 0 taken 8537 times.
✓ Branch 1 taken 1903468 times.
1912005 if (zero_result_cause != nullptr) { // Can be set by make_join_plan().
652
1/2
✓ Branch 0 taken 8537 times.
✗ Branch 1 not taken.
8537 create_access_paths_for_zero_rows();
653 8537 goto setup_subq_exit;
654 }
655
656
2/2
✓ Branch 0 taken 1903120 times.
✓ Branch 1 taken 348 times.
1903468 if (rollup_state == RollupState::NONE) {
657 /* Remove distinct if only const tables */
658 1903120 select_distinct &= !plan_is_const();
659 }
660
661
6/6
✓ Branch 0 taken 90938 times.
✓ Branch 1 taken 1812536 times.
✓ Branch 2 taken 87545 times.
✓ Branch 3 taken 3393 times.
✓ Branch 4 taken 85676 times.
✓ Branch 5 taken 1817798 times.
1991019 if (const_tables && !thd->locked_tables_mode &&
662
2/2
✓ Branch 0 taken 85676 times.
✓ Branch 1 taken 1869 times.
87545 !(query_block->active_options() & SELECT_NO_UNLOCK)) {
663 TABLE *ct[MAX_TABLES];
664
2/2
✓ Branch 0 taken 86796 times.
✓ Branch 1 taken 85677 times.
172473 for (uint i = 0; i < const_tables; i++) {
665 86796 ct[i] = best_ref[i]->table();
666
1/2
✓ Branch 0 taken 86797 times.
✗ Branch 1 not taken.
86796 ct[i]->file->ha_index_or_rnd_end();
667 }
668
1/2
✓ Branch 0 taken 85677 times.
✗ Branch 1 not taken.
85677 mysql_unlock_some_tables(thd, ct, const_tables);
669 }
670
4/4
✓ Branch 0 taken 604640 times.
✓ Branch 1 taken 1298835 times.
✓ Branch 2 taken 4080 times.
✓ Branch 3 taken 600560 times.
1903475 if (!where_cond && query_block->outer_join) {
671 /* Handle the case where we have an OUTER JOIN without a WHERE */
672
1/2
✓ Branch 0 taken 4080 times.
✗ Branch 1 not taken.
8160 where_cond = new Item_func_true(); // Always true
673 }
674
675 1903475 error = 0;
676 /*
677 Among the equal fields belonging to the same multiple equality
678 choose the one that is to be retrieved first and substitute
679 all references to these in where condition for a reference for
680 the selected field.
681 */
682
2/2
✓ Branch 0 taken 1302883 times.
✓ Branch 1 taken 600592 times.
1903475 if (where_cond) {
683 1302900 where_cond =
684
1/2
✓ Branch 0 taken 1302900 times.
✗ Branch 1 not taken.
1302883 substitute_for_best_equal_field(thd, where_cond, cond_equal, map2table);
685
2/4
✓ Branch 0 taken 1302900 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1302900 times.
1302900 if (thd->is_error()) {
686 error = 1;
687 DBUG_PRINT("error", ("Error from substitute_for_best_equal"));
688 return true;
689 }
690
1/2
✓ Branch 0 taken 1302899 times.
✗ Branch 1 not taken.
1302900 where_cond->update_used_tables();
691
3/6
✓ Branch 0 taken 1302900 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1302894 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1302899 DBUG_EXECUTE("where",
692 print_where(thd, where_cond, "after substitute_best_equal",
693 QT_ORDINARY););
694 }
695
696 /*
697 Perform the same optimization on field evaluation for all join conditions.
698 */
699
2/2
✓ Branch 0 taken 6384958 times.
✓ Branch 1 taken 1903453 times.
8288411 for (uint i = const_tables; i < tables; ++i) {
700 6384958 JOIN_TAB *const tab = best_ref[i];
701
6/6
✓ Branch 0 taken 3826540 times.
✓ Branch 1 taken 2558433 times.
✓ Branch 2 taken 403550 times.
✓ Branch 3 taken 3423000 times.
✓ Branch 4 taken 403550 times.
✓ Branch 5 taken 5981433 times.
6384958 if (tab->position() && tab->join_cond()) {
702 807097 tab->set_join_cond(substitute_for_best_equal_field(
703
1/2
✓ Branch 0 taken 403547 times.
✗ Branch 1 not taken.
403550 thd, tab->join_cond(), tab->cond_equal, map2table));
704
2/4
✓ Branch 0 taken 403544 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 403544 times.
403545 if (thd->is_error()) {
705 error = 1;
706 DBUG_PRINT("error", ("Error from substitute_for_best_equal"));
707 return true;
708 }
709
1/2
✓ Branch 0 taken 403550 times.
✗ Branch 1 not taken.
403544 tab->join_cond()->update_used_tables();
710
1/2
✓ Branch 0 taken 403549 times.
✗ Branch 1 not taken.
403550 if (tab->join_cond())
711
1/2
✓ Branch 0 taken 403521 times.
✗ Branch 1 not taken.
403549 tab->join_cond()->walk(&Item::cast_incompatible_args,
712 enum_walk::POSTFIX, nullptr);
713 }
714 }
715
716
3/4
✓ Branch 0 taken 1903461 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1903458 times.
1903453 if (init_ref_access()) {
717 3 error = 1;
718
3/8
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
3 DBUG_PRINT("error", ("Error from init_ref_access"));
719 3 return true;
720 }
721
722 // Update table dependencies after assigning ref access fields
723
1/2
✓ Branch 0 taken 1903453 times.
✗ Branch 1 not taken.
1903458 update_depend_map();
724
725
1/2
✓ Branch 0 taken 1903457 times.
✗ Branch 1 not taken.
1903453 THD_STAGE_INFO(thd, stage_preparing);
726
727
3/4
✓ Branch 0 taken 1903449 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2920 times.
✓ Branch 3 taken 1900529 times.
1903457 if (make_join_query_block(this, where_cond)) {
728
3/4
✓ Branch 0 taken 2921 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2919 times.
2920 if (thd->is_error()) return true;
729
730 2919 zero_result_cause = "Impossible WHERE noticed after reading const tables";
731
1/2
✓ Branch 0 taken 2918 times.
✗ Branch 1 not taken.
2919 create_access_paths_for_zero_rows();
732 2918 goto setup_subq_exit;
733 }
734
735 // Inject cast nodes into the WHERE conditions
736
2/2
✓ Branch 0 taken 1218968 times.
✓ Branch 1 taken 681561 times.
1900529 if (where_cond)
737
1/2
✓ Branch 0 taken 1218970 times.
✗ Branch 1 not taken.
1218968 where_cond->walk(&Item::cast_incompatible_args, enum_walk::POSTFIX,
738 nullptr);
739
740 1900531 error = -1; /* if goto err */
741
742
2/4
✓ Branch 0 taken 1900538 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1900538 times.
1900531 if (optimize_distinct_group_order()) return true;
743
744
4/4
✓ Branch 0 taken 1845139 times.
✓ Branch 1 taken 55396 times.
✓ Branch 2 taken 57688 times.
✓ Branch 3 taken 1842847 times.
3745677 if ((query_block->active_options() & SELECT_NO_JOIN_CACHE) ||
745
2/2
✓ Branch 0 taken 2290 times.
✓ Branch 1 taken 1842849 times.
1845139 query_block->ftfunc_list->elements)
746 57688 no_jbuf_after = 0;
747
748 /* Perform FULLTEXT search before all regular searches */
749
7/8
✓ Branch 0 taken 2294 times.
✓ Branch 1 taken 1898242 times.
✓ Branch 2 taken 2293 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 2290 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 1900532 times.
1900535 if (query_block->has_ft_funcs() && optimize_fts_query()) return true;
750
751 /*
752 By setting child_subquery_can_materialize so late we gain the following:
753 JOIN::compare_costs_of_subquery_strategies() can test this variable to
754 know if we are have finished evaluating constant conditions, which itself
755 helps determining fanouts.
756 */
757 1900532 child_subquery_can_materialize = true;
758
759 /*
760 It's necessary to check const part of HAVING cond as
761 there is a chance that some cond parts may become
762 const items after make_join_plan() (for example
763 when Item is a reference to const table field from
764 outer join).
765 This check is performed only for those conditions
766 which do not use aggregate functions. In such case
767 temporary table may not be used and const condition
768 elements may be lost during further having
769 condition transformation in JOIN::exec.
770 */
771
8/8
✓ Branch 0 taken 3554 times.
✓ Branch 1 taken 1896978 times.
✓ Branch 2 taken 851 times.
✓ Branch 3 taken 2703 times.
✓ Branch 4 taken 26 times.
✓ Branch 5 taken 825 times.
✓ Branch 6 taken 26 times.
✓ Branch 7 taken 1900506 times.
1900532 if (having_cond && !having_cond->has_aggregation() && (const_tables > 0)) {
772
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 having_cond->update_used_tables();
773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (remove_eq_conds(thd, having_cond, &having_cond,
774
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 &query_block->having_value)) {
775 error = 1;
776 DBUG_PRINT("error", ("Error from remove_eq_conds"));
777 return true;
778 }
779
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 19 times.
26 if (query_block->having_value == Item::COND_FALSE) {
780
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
14 having_cond = new Item_func_false();
781 7 zero_result_cause =
782 "Impossible HAVING noticed after reading const tables";
783
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 create_access_paths_for_zero_rows();
784 7 goto setup_subq_exit;
785 }
786 }
787
788 // Inject cast nodes into the HAVING conditions
789
2/2
✓ Branch 0 taken 3543 times.
✓ Branch 1 taken 1896982 times.
1900525 if (having_cond)
790
1/2
✓ Branch 0 taken 3543 times.
✗ Branch 1 not taken.
3543 having_cond->walk(&Item::cast_incompatible_args, enum_walk::POSTFIX,
791 nullptr);
792
793 // Traverse the expressions and inject cast nodes to compatible data types,
794 // if needed.
795
7/12
✓ Branch 0 taken 1900514 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1900526 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8702409 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8702413 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 10602935 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8702406 times.
✓ Branch 11 taken 1900529 times.
10602938 for (Item *item : *fields) {
796
1/2
✓ Branch 0 taken 8702413 times.
✗ Branch 1 not taken.
8702409 item->walk(&Item::cast_incompatible_args, enum_walk::POSTFIX, nullptr);
797 }
798
799 // Also GROUP BY expressions, so that find_in_group_list() doesn't
800 // inadvertently fail because the SELECT list has casts that GROUP BY doesn't.
801
2/2
✓ Branch 0 taken 19318 times.
✓ Branch 1 taken 1900529 times.
1919847 for (ORDER *ord = group_list.order; ord != nullptr; ord = ord->next) {
802 19318 (*ord->item)
803
1/2
✓ Branch 0 taken 19318 times.
✗ Branch 1 not taken.
19318 ->walk(&Item::cast_incompatible_args, enum_walk::POSTFIX, nullptr);
804 }
805
806
2/2
✓ Branch 0 taken 332 times.
✓ Branch 1 taken 1900197 times.
1900529 if (rollup_state != RollupState::NONE) {
807 /*
808 Fields may have been replaced by Item_rollup_group_item, so
809 recalculate the number of fields and functions for this query block.
810 */
811
812 // JOIN::optimize_rollup() may set allow_group_via_temp_table = false,
813 // and we must not undo that.
814 332 const bool save_allow_group_via_temp_table =
815 tmp_table_param.allow_group_via_temp_table;
816
817
1/2
✓ Branch 0 taken 332 times.
✗ Branch 1 not taken.
332 count_field_types(query_block, &tmp_table_param, *fields, false, false);
818 332 tmp_table_param.allow_group_via_temp_table =
819 save_allow_group_via_temp_table;
820 }
821
822 // See if this subquery can be evaluated with subselect_indexsubquery_engine
823
3/4
✓ Branch 0 taken 1900529 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 147 times.
✓ Branch 3 taken 1900382 times.
1900529 if (const int ret = replace_index_subquery()) {
824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 147 times.
147 if (ret == -1) {
825 // Error (e.g. allocation failed, or some condition was attempted
826 // evaluated statically and failed).
827 return true;
828 }
829
830
1/2
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
147 create_access_paths_for_index_subquery();
831
1/2
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
147 set_plan_state(PLAN_READY);
832 /*
833 We leave optimize() because the rest of it is only about order/group
834 which those subqueries don't have and about setting up plan which
835 we're not going to use due to different execution method.
836 */
837 147 return false;
838 }
839
840 {
841 /*
842 If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the first
843 table (it does not make sense for other tables) then we cannot do join
844 buffering.
845 */
846
2/2
✓ Branch 0 taken 1813737 times.
✓ Branch 1 taken 86644 times.
1900382 if (!plan_is_const()) {
847 1813737 const TABLE *const first = best_ref[const_tables]->table();
848
6/6
✓ Branch 0 taken 126595 times.
✓ Branch 1 taken 1687142 times.
✓ Branch 2 taken 125027 times.
✓ Branch 3 taken 1556 times.
✓ Branch 4 taken 1568 times.
✓ Branch 5 taken 1812157 times.
3625906 if ((first->force_index_order && !order.empty()) ||
849
4/4
✓ Branch 0 taken 125033 times.
✓ Branch 1 taken 1687136 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 125021 times.
1812169 (first->force_index_group && !group_list.empty()))
850 1568 no_jbuf_after = 0;
851 }
852
853 1900369 bool simple_sort = true;
854 1900369 Table_map_restorer deps_lateral(&deps_of_remaining_lateral_derived_tables);
855 // Check whether join cache could be used
856
2/2
✓ Branch 0 taken 6381384 times.
✓ Branch 1 taken 1900397 times.
8281781 for (uint i = const_tables; i < tables; i++) {
857 6381384 JOIN_TAB *const tab = best_ref[i];
858
2/2
✓ Branch 0 taken 2555097 times.
✓ Branch 1 taken 3826299 times.
6381384 if (!tab->position()) continue;
859
2/4
✓ Branch 0 taken 3826295 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3826295 times.
3826299 if (setup_join_buffering(tab, this, no_jbuf_after)) return true;
860
2/2
✓ Branch 0 taken 120240 times.
✓ Branch 1 taken 3706058 times.
3826295 if (tab->use_join_cache() != JOIN_CACHE::ALG_NONE) simple_sort = false;
861
3/4
✓ Branch 0 taken 2131 times.
✓ Branch 1 taken 3824182 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2134 times.
3826298 assert(tab->type() != JT_FT ||
862 tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
863
6/6
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 3824162 times.
✓ Branch 2 taken 562 times.
✓ Branch 3 taken 1592 times.
✓ Branch 4 taken 562 times.
✓ Branch 5 taken 3825754 times.
3826316 if (has_lateral && get_lateral_deps(*best_ref[i]) != 0) {
864 562 deps_of_remaining_lateral_derived_tables =
865
1/2
✓ Branch 0 taken 562 times.
✗ Branch 1 not taken.
562 calculate_deps_of_remaining_lateral_derived_tables(all_table_map,
866 i + 1);
867 }
868 }
869
2/2
✓ Branch 0 taken 104354 times.
✓ Branch 1 taken 1796043 times.
1900397 if (!simple_sort) {
870 /*
871 A join buffer is used for this table. We here inform the optimizer
872 that it should not rely on rows of the first non-const table being in
873 order thanks to an index scan; indeed join buffering of the present
874 table subsequently changes the order of rows.
875 */
876 104354 simple_order = simple_group = false;
877 }
878
1/2
✓ Branch 0 taken 1900382 times.
✗ Branch 1 not taken.
1900397 }
879
880
6/6
✓ Branch 0 taken 1813739 times.
✓ Branch 1 taken 86643 times.
✓ Branch 2 taken 629579 times.
✓ Branch 3 taken 1184160 times.
✓ Branch 4 taken 629579 times.
✓ Branch 5 taken 1270803 times.
1900382 if (!plan_is_const() && !order.empty()) {
881 /*
882 Force using of tmp table if sorting by a SP or UDF function due to
883 their expensive and probably non-deterministic nature.
884 */
885
2/2
✓ Branch 0 taken 982026 times.
✓ Branch 1 taken 629527 times.
1611553 for (ORDER *tmp_order = order.order; tmp_order;
886 981974 tmp_order = tmp_order->next) {
887 982026 Item *item = *tmp_order->item;
888
3/4
✓ Branch 0 taken 982024 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 981974 times.
982026 if (item->is_expensive()) {
889 /* Force tmp table without sort */
890 50 simple_order = simple_group = false;
891 50 break;
892 }
893 }
894 }
895
896 /*
897 Check if we need to create a temporary table prior to any windowing.
898
899 (1) If there is ROLLUP, which happens before DISTINCT, windowing and ORDER
900 BY, any of those clauses needs the result of ROLLUP in a tmp table.
901
902 Rows which ROLLUP adds to the result are visible only to DISTINCT,
903 windowing and ORDER BY which we handled above. So for the rest of
904 conditions ((2), etc), we can do as if there were no ROLLUP.
905
906 (2) If all tables are constant, the query's result is guaranteed to have 0
907 or 1 row only, so all SQL clauses discussed below (DISTINCT, ORDER BY,
908 GROUP BY, windowing, SQL_BUFFER_RESULT) are useless and need no tmp
909 table.
910
911 (3) If there is GROUP BY which isn't resolved by using an index or sorting
912 the first table, we need a tmp table to compute the grouped rows.
913 GROUP BY happens before windowing; so it is a pre-windowing tmp
914 table.
915
916 (4) (5) If there is DISTINCT, or ORDER BY which isn't resolved by using an
917 index or sorting the first table, those clauses need an input tmp table.
918 If we have windowing, as those clauses are used after windowing, they can
919 use the last window's tmp table.
920
921 (6) If there are different ORDER BY and GROUP BY orders, ORDER BY needs an
922 input tmp table, so it's like (5).
923
924 (7) If the user wants us to buffer the result, we need a tmp table. But
925 windowing creates one anyway, and so does the materialization of a derived
926 table.
927
928 See also the computation of Window::m_short_circuit,
929 where we make sure to create a tmp table if the clauses above want one.
930
931 (8) If the first windowing step needs sorting, filesort() will be used; it
932 can sort one table but not a join of tables, so we need a tmp table
933 then. If GROUP BY was optimized away, the pre-windowing result is 0 or 1
934 row so doesn't need sorting.
935 */
936
937
4/4
✓ Branch 0 taken 332 times.
✓ Branch 1 taken 1900048 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 1900268 times.
1900712 if (rollup_state != RollupState::NONE && // (1)
938
6/6
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 256 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 220 times.
332 (select_distinct || has_windows || !order.empty()))
939 112 need_tmp_before_win = true;
940
941 /*
942 If we have full-text columns involved in aggregation, we need to
943 materialize it, as the saving and loading of rows in AggregateIterator
944 does not include FTS information. If we have multiple tables, we'll
945 have a materialization (either because we're aggregating into a temporary
946 table, or because we always materialize before further operations),
947 and if we have a GROUP BY, we'll either have an aggregate-to-table
948 or a sort, which also fixes the issue. However, in the case of a single
949 table and implicit grouping, we need to force the temporary table here.
950 */
951
2/2
✓ Branch 0 taken 417408 times.
✓ Branch 1 taken 1482847 times.
1900255 if (!need_tmp_before_win && implicit_grouping &&
952
9/10
✓ Branch 0 taken 1900255 times.
✓ Branch 1 taken 125 times.
✓ Branch 2 taken 353574 times.
✓ Branch 3 taken 63834 times.
✓ Branch 4 taken 353591 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 82 times.
✓ Branch 7 taken 353492 times.
✓ Branch 8 taken 82 times.
✓ Branch 9 taken 1900281 times.
4154209 primary_tables - const_tables == 1 && order.empty() &&
953 353591 best_ref[const_tables]->table_ref->is_fulltext_searched()) {
954
8/14
✓ Branch 0 taken 82 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 82 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 82 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 82 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 80 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 162 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 82 times.
✓ Branch 13 taken 80 times.
162 for (Item *item : VisibleFields(*fields)) {
955 82 need_tmp_before_win |=
956
1/2
✓ Branch 0 taken 82 times.
✗ Branch 1 not taken.
82 contains_function_of_type(item, Item_func::FT_FUNC);
957
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 80 times.
82 if (need_tmp_before_win) break;
958 }
959 }
960
961
2/2
✓ Branch 0 taken 1813718 times.
✓ Branch 1 taken 86637 times.
1900363 if (!plan_is_const()) // (2)
962 {
963
2/2
✓ Branch 0 taken 10273 times.
✓ Branch 1 taken 1569 times.
1825560 if ((!group_list.empty() && !simple_group) || // (3)
964
4/4
✓ Branch 0 taken 1811077 times.
✓ Branch 1 taken 1078 times.
✓ Branch 2 taken 1810048 times.
✓ Branch 3 taken 1029 times.
1812155 (!has_windows && (select_distinct || // (4)
965
4/4
✓ Branch 0 taken 628659 times.
✓ Branch 1 taken 1181386 times.
✓ Branch 2 taken 357402 times.
✓ Branch 3 taken 271257 times.
1810048 (!order.empty() && !simple_order) || // (5)
966
4/4
✓ Branch 0 taken 9910 times.
✓ Branch 1 taken 1528885 times.
✓ Branch 2 taken 9773 times.
✓ Branch 3 taken 137 times.
1538788 (!group_list.empty() && !order.empty()))) || // (6)
967
2/2
✓ Branch 0 taken 7056 times.
✓ Branch 1 taken 1532678 times.
1539737 ((query_block->active_options() & OPTION_BUFFER_RESULT) &&
968
1/2
✓ Branch 0 taken 7056 times.
✗ Branch 1 not taken.
7056 !has_windows &&
969
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7049 times.
7056 !(query_expression()->derived_table &&
970 7 query_expression()
971
8/8
✓ Branch 0 taken 11842 times.
✓ Branch 1 taken 1801882 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1078 times.
✓ Branch 5 taken 1531602 times.
✓ Branch 6 taken 281063 times.
✓ Branch 7 taken 1532662 times.
3628527 ->derived_table->uses_materialization())) || // (7)
972
4/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1060 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 5 times.
1096 (has_windows && (primary_tables - const_tables) > 1 && // (8)
973
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
31 m_windows[0]->needs_sorting() && !group_optimized_away))
974 281063 need_tmp_before_win = true;
975 }
976
977
4/6
✓ Branch 0 taken 1900374 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✓ Branch 3 taken 1900347 times.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
1900362 DBUG_EXECUTE("info", TEST_join(this););
978
979
2/4
✓ Branch 0 taken 1900377 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1900377 times.
1900374 if (alloc_qep(tables)) return (error = 1); /* purecov: inspected */
980
981
2/2
✓ Branch 0 taken 1813734 times.
✓ Branch 1 taken 86643 times.
1900377 if (!plan_is_const()) {
982 // Test if we can use an index instead of sorting
983
1/2
✓ Branch 0 taken 1813737 times.
✗ Branch 1 not taken.
1813734 test_skip_sort();
984
985
3/4
✓ Branch 0 taken 1813723 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1813722 times.
1813737 if (finalize_table_conditions()) return true;
986 }
987
988
2/4
✓ Branch 0 taken 1900381 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1900381 times.
1900365 if (make_join_readinfo(this, no_jbuf_after))
989 return true; /* purecov: inspected */
990
991
3/4
✓ Branch 0 taken 1900380 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1900379 times.
1900381 if (make_tmp_tables_info()) return true;
992
993 /*
994 If we decided to not sort after all, update the cost of the JOIN.
995 Windowing sorts are handled elsewhere
996 */
997
4/4
✓ Branch 0 taken 440286 times.
✓ Branch 1 taken 1460093 times.
✓ Branch 2 taken 20888 times.
✓ Branch 3 taken 1879491 times.
2340665 if (sort_cost > 0.0 &&
998
2/2
✓ Branch 0 taken 20888 times.
✓ Branch 1 taken 419398 times.
440286 !explain_flags.any(ESP_USING_FILESORT, ESC_WINDOWING)) {
999 20888 best_read -= sort_cost;
1000 20888 sort_cost = 0.0;
1001 }
1002
1003
1/2
✓ Branch 0 taken 1900379 times.
✗ Branch 1 not taken.
1900379 count_field_types(query_block, &tmp_table_param, *fields, false, false);
1004
1005
1/2
✓ Branch 0 taken 1900363 times.
✗ Branch 1 not taken.
1900379 create_access_paths();
1006
1007 // Creating iterators may evaluate a constant hash join condition, which may
1008 // fail:
1009
2/4
✓ Branch 0 taken 1900373 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1900373 times.
1900363 if (thd->is_error()) return true;
1010
1011 /*
1012 At this stage, we have set up an AccessPath 'plan'. Traverse the
1013 AccessPath structures and find components which may be offloaded to
1014 the engines. This process is allowed to modify the AccessPath itself.
1015 (Removing/modifying FILTERs where pushed to the engines, change JOIN*
1016 algorithms being used, modify aggregate expressions, ...).
1017 This will later affects which type of Iterator we should create. Thus no
1018 Iterators should be set up until after push_to_engines() has completed.
1019
1020 Note that when the Hypergraph optimizer is used, there is an entirely
1021 different code path to push_to_engine(). (We create the AcccesPath directly
1022 instead of converting the QEP_TABs into an AccessPath structure).
1023 In the HG case we push_to_engine() when FinalizePlanForQueryBlock()
1024 has finalized the 'plan'.
1025 */
1026
2/4
✓ Branch 0 taken 1900369 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1900369 times.
1900373 if (push_to_engines()) return true;
1027
1028 // Make plan visible for EXPLAIN
1029
1/2
✓ Branch 0 taken 1900378 times.
✗ Branch 1 not taken.
1900369 set_plan_state(PLAN_READY);
1030
1031
3/4
✓ Branch 0 taken 1892149 times.
✓ Branch 1 taken 8224 times.
✓ Branch 2 taken 1892156 times.
✗ Branch 3 not taken.
1900378 DEBUG_SYNC(thd, "after_join_optimize");
1032
1033 1900380 error = 0;
1034 1900380 return false;
1035
1036 29496 setup_subq_exit:
1037
1038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29496 times.
29496 assert(zero_result_cause != nullptr);
1039
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29496 times.
29496 assert(m_root_access_path != nullptr);
1040 /*
1041 Even with zero matching rows, subqueries in the HAVING clause may
1042 need to be evaluated if there are aggregate functions in the
1043 query. If this JOIN is part of an outer query, subqueries in HAVING may
1044 be evaluated several times in total; so subquery materialization makes
1045 sense.
1046 */
1047 29496 child_subquery_can_materialize = true;
1048
1049
1/2
✓ Branch 0 taken 29497 times.
✗ Branch 1 not taken.
29496 trace_steps.end(); // because all steps are done
1050
2/4
✓ Branch 0 taken 29496 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29497 times.
✗ Branch 3 not taken.
29497 Opt_trace_object(trace, "empty_result").add_alnum("cause", zero_result_cause);
1051
1052 29497 having_for_explain = having_cond;
1053 29497 error = 0;
1054
1055
3/4
✓ Branch 0 taken 29497 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11463 times.
✓ Branch 3 taken 18034 times.
29497 if (!qep_tab && best_ref) {
1056 /*
1057 After creation of JOIN_TABs in make_join_plan(), we have shortcut due to
1058 some zero_result_cause. For simplification, if we have JOIN_TABs we
1059 want QEP_TABs too.
1060 */
1061
2/4
✓ Branch 0 taken 11463 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11463 times.
11463 if (alloc_qep(tables)) return true; /* purecov: inspected */
1062
1/2
✓ Branch 0 taken 11462 times.
✗ Branch 1 not taken.
11463 unplug_join_tabs();
1063 }
1064
1065
1/2
✓ Branch 0 taken 29497 times.
✗ Branch 1 not taken.
29496 set_plan_state(ZERO_RESULT);
1066 29497 return false;
1067 9923746 }
1068
1069 150 void JOIN::change_to_access_path_without_in2exists() {
1070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 150 times.
150 if (m_root_access_path_no_in2exists != nullptr) {
1071 m_root_access_path = m_root_access_path_no_in2exists;
1072 }
1073 150 }
1074
1075 24416 void JOIN::create_access_paths_for_zero_rows() {
1076
2/2
✓ Branch 0 taken 8238 times.
✓ Branch 1 taken 16178 times.
24416 if (send_row_on_empty_set()) {
1077 // Aggregate no rows into an aggregate row.
1078 8238 m_root_access_path =
1079 8238 NewZeroRowsAggregatedAccessPath(thd, zero_result_cause);
1080 8238 m_root_access_path =
1081 8238 attach_access_paths_for_having_and_limit(m_root_access_path);
1082 } else {
1083 // Send no row at all (so also no need to check HAVING or LIMIT).
1084 16178 m_root_access_path = NewZeroRowsAccessPath(thd, zero_result_cause);
1085 }
1086 24416 m_root_access_path =
1087 24417 attach_access_path_for_update_or_delete(m_root_access_path);
1088 24416 }
1089
1090 /**
1091 Push (parts of) the query execution down to the storage engines if they
1092 can provide faster execution of the query, or part of it.
1093
1094 The handler will inspect the QEP through the
1095 AQP (Abstract Query Plan) and extract from it whatever
1096 it might implement of pushed execution.
1097
1098 It is the responsibility of the handler to store
1099 any information it need for the later execution of
1100 pushed queries and conditions.
1101
1102 @retval false Success.
1103 @retval true Error, error code saved in member JOIN::error.
1104 */
1105 1900717 bool JOIN::push_to_engines() {
1106
1/2
✓ Branch 0 taken 1900728 times.
✗ Branch 1 not taken.
1900717 DBUG_TRACE;
1107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1900728 times.
1900728 assert(m_root_access_path != nullptr);
1108
1109
2/2
✓ Branch 0 taken 3915155 times.
✓ Branch 1 taken 1900728 times.
5815883 for (TABLE_LIST *tl = query_block->leaf_tables; tl; tl = tl->next_leaf) {
1110
1/2
✓ Branch 0 taken 3915155 times.
✗ Branch 1 not taken.
3915155 const handlerton *hton = tl->table->file->hton_supporting_engine_pushdown();
1111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3915155 times.
3915155 if (hton != nullptr) { // Involved an engine supporting pushdown.
1112 if (unlikely(hton->push_to_engine(thd, m_root_access_path, this))) {
1113 return true;
1114 }
1115 break; // Assume that at most a single handlerton per query support
1116 // pushdown
1117 }
1118 }
1119 1900728 return false;
1120 1900728 }
1121
1122 /**
1123 Substitute all expressions in the WHERE condition and ORDER/GROUP lists
1124 that match generated columns (GC) expressions with GC fields, if any.
1125
1126 @details This function does 3 things:
1127 1) Creates list of all GC fields that are a part of a key and the GC
1128 expression is a function. All query tables are scanned. If there's no
1129 such fields, function exits.
1130 2) By means of Item::compile() WHERE clause is transformed.
1131 @see Item_func::gc_subst_transformer() for details.
1132 3) If there's ORDER/GROUP BY clauses, this function tries to substitute
1133 expressions in these lists with GC too. It removes from the list of
1134 indexed GC all elements which index blocked by hints. This is done to
1135 reduce amount of further work. Next it goes through ORDER/GROUP BY list
1136 and matches the expression in it against GC expressions in indexed GC
1137 list. When a match is found, the expression is replaced with a new
1138 Item_field for the matched GC field. Also, this new field is added to
1139 the hidden part of all_fields list.
1140
1141 @param thd thread handle
1142 @param query_block the current select
1143 @param where_cond the WHERE condition, possibly NULL
1144 @param group_list the GROUP BY clause, possibly NULL
1145 @param order the ORDER BY clause, possibly NULL
1146
1147 @return true if the GROUP BY clause or the ORDER BY clause was
1148 changed, false otherwise
1149 */
1150
1151 1993185 bool substitute_gc(THD *thd, Query_block *query_block, Item *where_cond,
1152 ORDER *group_list, ORDER *order) {
1153 1993185 List<Field> indexed_gc;
1154 1993228 Opt_trace_context *const trace = &thd->opt_trace;
1155
1/2
✓ Branch 0 taken 1993245 times.
✗ Branch 1 not taken.
1993228 Opt_trace_object trace_wrapper(trace);
1156
1/2
✓ Branch 0 taken 1993270 times.
✗ Branch 1 not taken.
1993245 Opt_trace_object subst_gc(trace, "substitute_generated_columns");
1157
1158 // Collect all GCs that are a part of a key
1159
2/2
✓ Branch 0 taken 3993021 times.
✓ Branch 1 taken 1993380 times.
5986401 for (TABLE_LIST *tl = query_block->leaf_tables; tl; tl = tl->next_leaf) {
1160
2/2
✓ Branch 0 taken 410588 times.
✓ Branch 1 taken 3582433 times.
3993021 if (tl->table->s->keys == 0) continue;
1161
2/2
✓ Branch 0 taken 34601132 times.
✓ Branch 1 taken 3582543 times.
38183675 for (uint i = 0; i < tl->table->s->fields; i++) {
1162 34601132 Field *fld = tl->table->field[i];
1163 34601132 if (fld->is_gcol() &&
1164
2/2
✓ Branch 0 taken 92307 times.
✓ Branch 1 taken 18542 times.
110849 !(fld->part_of_key.is_clear_all() &&
1165
6/6
✓ Branch 0 taken 110849 times.
✓ Branch 1 taken 34490340 times.
✓ Branch 2 taken 13258 times.
✓ Branch 3 taken 79049 times.
✓ Branch 4 taken 25244 times.
✓ Branch 5 taken 34575919 times.
34725270 fld->part_of_prefixkey.is_clear_all()) &&
1166
3/4
✓ Branch 0 taken 31774 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25244 times.
✓ Branch 3 taken 6530 times.
31800 fld->gcol_info->expr_item->can_be_substituted_for_gc()) {
1167 // Don't check allowed keys here as conditions/group/order use
1168 // different keymaps for that.
1169
1/2
✓ Branch 0 taken 25323 times.
✗ Branch 1 not taken.
25244 indexed_gc.push_back(fld);
1170 }
1171 }
1172 }
1173 // No GC in the tables used in the query
1174
2/2
✓ Branch 0 taken 1968781 times.
✓ Branch 1 taken 24599 times.
1993380 if (indexed_gc.elements == 0) return false;
1175
1176
2/2
✓ Branch 0 taken 24323 times.
✓ Branch 1 taken 276 times.
24599 if (where_cond) {
1177 // Item_func::compile will dereference this pointer, provide valid value.
1178 24323 uchar i, *dummy = &i;
1179
1/2
✓ Branch 0 taken 24323 times.
✗ Branch 1 not taken.
24323 if (where_cond->compile(&Item::gc_subst_analyzer, &dummy,
1180 &Item::gc_subst_transformer,
1181
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 24321 times.
24323 pointer_cast<uchar *>(&indexed_gc)) == nullptr)
1182 2 return true;
1183
1/2
✓ Branch 0 taken 24321 times.
✗ Branch 1 not taken.
24321 subst_gc.add("resulting_condition", where_cond);
1184 }
1185
1186 // An error occur during substitution. Let caller handle it.
1187
2/4
✓ Branch 0 taken 24493 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24493 times.
24597 if (thd->is_error()) return false;
1188
1189
4/4
✓ Branch 0 taken 24457 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 24150 times.
✓ Branch 3 taken 307 times.
24493 if (!(group_list || order)) return false;
1190 // Filter out GCs that do not have index usable for GROUP/ORDER
1191 Field *gc;
1192
1/2
✓ Branch 0 taken 343 times.
✗ Branch 1 not taken.
343 List_iterator<Field> li(indexed_gc);
1193
1194
2/2
✓ Branch 0 taken 489 times.
✓ Branch 1 taken 343 times.
832 while ((gc = li++)) {
1195 489 Key_map tkm = gc->part_of_key;
1196
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 380 times.
869 tkm.intersect(group_list ? gc->table->keys_in_use_for_group_by
1197 380 : gc->table->keys_in_use_for_order_by);
1198
3/4
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 359 times.
✓ Branch 2 taken 130 times.
✗ Branch 3 not taken.
489 if (tkm.is_clear_all()) li.remove();
1199 }
1200
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 224 times.
343 if (!indexed_gc.elements) return false;
1201
1202 // Index could be used for ORDER only if there is no GROUP
1203
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 188 times.
224 ORDER *list = group_list ? group_list : order;
1204 224 bool changed = false;
1205
2/2
✓ Branch 0 taken 396 times.
✓ Branch 1 taken 224 times.
620 for (ORDER *ord = list; ord; ord = ord->next) {
1206 396 li.rewind();
1207
3/4
✓ Branch 0 taken 396 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 13 times.
396 if (!(*ord->item)->can_be_substituted_for_gc()) continue;
1208
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 12 times.
25 while ((gc = li++)) {
1209 Item_field *const field =
1210
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 get_gc_for_expr(*ord->item, gc, gc->result_type());
1211
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12 times.
13 if (field != nullptr) {
1212 1 changed = true;
1213 /* Add new field to field list. */
1214
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 Item **new_field = query_block->add_hidden_item(field);
1215
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 thd->change_item_tree(ord->item, *new_field);
1216 1 query_block->hidden_items_from_optimization++;
1217 1 break;
1218 }
1219 }
1220 }
1221 // An error occur during substitution. Let caller handle it.
1222
2/4
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 224 times.
224 if (thd->is_error()) return false;
1223
1224
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 223 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 224 times.
224 if (changed && trace->is_started()) {
1225 String str;
1226 Query_block::print_order(
1227 thd, &str, list,
1228 enum_query_type(QT_TO_SYSTEM_CHARSET | QT_SHOW_SELECT_NUMBER |
1229 QT_NO_DEFAULT_DB));
1230 subst_gc.add_utf8(group_list ? "resulting_GROUP_BY" : "resulting_ORDER_BY",
1231 str.ptr(), str.length());
1232 }
1233 224 return changed;
1234 1993276 }
1235
1236 /**
1237 Sets the plan's state of the JOIN. This is always the final step of
1238 optimization; starting from this call, we expose the plan to other
1239 connections (via EXPLAIN CONNECTION) so the plan has to be final.
1240 keyread_optim is set here.
1241 */
1242 19847142 void JOIN::set_plan_state(enum_plan_state plan_state_arg) {
1243 // A plan should not change to another plan:
1244
3/4
✓ Branch 0 taken 9923556 times.
✓ Branch 1 taken 9923586 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9923556 times.
19847142 assert(plan_state_arg == NO_PLAN || plan_state == NO_PLAN);
1245
4/4
✓ Branch 0 taken 9923908 times.
✓ Branch 1 taken 9923234 times.
✓ Branch 2 taken 9923554 times.
✓ Branch 3 taken 354 times.
19847142 if (plan_state == NO_PLAN && plan_state_arg != NO_PLAN) {
1246
2/2
✓ Branch 0 taken 1911981 times.
✓ Branch 1 taken 8011573 times.
9923554 if (qep_tab != nullptr) {
1247 /*
1248 We want to cover primary tables, tmp tables. Note that
1249 make_tmp_tables_info() may have added a sort to the first non-const
1250 primary table, so it's important to do this assignment after
1251 make_tmp_tables_info().
1252 */
1253
2/2
✓ Branch 0 taken 6398096 times.
✓ Branch 1 taken 1911985 times.
8310081 for (uint i = const_tables; i < tables; ++i) {
1254 6398096 qep_tab[i].set_condition_optim();
1255 6398096 qep_tab[i].set_keyread_optim();
1256 }
1257 }
1258 }
1259
1260
2/2
✓ Branch 0 taken 19800061 times.
✓ Branch 1 taken 47101 times.
19847146 DEBUG_SYNC(thd, "before_set_plan");
1261
1262 // If SQLCOM_END, no thread is explaining our statement anymore.
1263 19847183 const bool need_lock = thd->query_plan.get_command() != SQLCOM_END;
1264
1265
2/2
✓ Branch 0 taken 10027413 times.
✓ Branch 1 taken 9819760 times.
19847173 if (need_lock) thd->lock_query_plan();
1266 19847175 plan_state = plan_state_arg;
1267
2/2
✓ Branch 0 taken 10027415 times.
✓ Branch 1 taken 9819760 times.
19847175 if (need_lock) thd->unlock_query_plan();
1268 19847182 }
1269
1270 1911971 bool JOIN::alloc_qep(uint n) {
1271 static_assert(MAX_TABLES <= INT_MAX8, "plan_idx needs to be wide enough.");
1272
1273
3/6
✓ Branch 0 taken 1911974 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1911975 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1911982 times.
✗ Branch 5 not taken.
1911971 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
1274
1275 1911983 qep_tab = new (thd->mem_root)
1276
4/6
✓ Branch 0 taken 1911983 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1911984 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8410959 times.
✓ Branch 5 taken 1911971 times.
12234908 QEP_TAB[n + 1]; // The last one holds only the final op_type.
1277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1911971 times.
1911971 if (!qep_tab) return true; /* purecov: inspected */
1278
2/2
✓ Branch 0 taken 6499068 times.
✓ Branch 1 taken 1911975 times.
8411039 for (uint i = 0; i < n; ++i) qep_tab[i].init(best_ref[i]);
1279 1911975 return false;
1280 }
1281
1282 6499059 void QEP_TAB::init(JOIN_TAB *jt) {
1283 6499059 jt->share_qs(this);
1284 6499075 set_table(table()); // to update table()->reginfo.qep_tab
1285 6499067 table_ref = jt->table_ref;
1286 6499067 }
1287
1288 /// @returns semijoin strategy for this table.
1289 87463 uint QEP_TAB::get_sj_strategy() const {
1290
2/2
✓ Branch 0 taken 86338 times.
✓ Branch 1 taken 1125 times.
87463 if (first_sj_inner() == NO_PLAN_IDX) return SJ_OPT_NONE;
1291 1125 const uint s = join()->qep_tab[first_sj_inner()].position()->sj_strategy;
1292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1125 times.
1125 assert(s != SJ_OPT_NONE);
1293 1125 return s;
1294 }
1295
1296 /**
1297 Return the index used for a table in a QEP
1298
1299 The various access methods have different places where the index/key
1300 number is stored, so this function is needed to return the correct value.
1301
1302 @returns index number, or MAX_KEY if not applicable.
1303
1304 JT_SYSTEM and JT_ALL does not use an index, and will always return MAX_KEY.
1305
1306 JT_INDEX_MERGE supports more than one index. Hence MAX_KEY is returned and
1307 a further inspection is needed.
1308 */
1309 10575 uint QEP_TAB::effective_index() const {
1310
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 615 times.
✓ Branch 2 taken 2504 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 336 times.
✓ Branch 5 taken 7096 times.
10575 switch (type()) {
1311 case JT_SYSTEM:
1312 assert(ref().key == -1);
1313 return MAX_KEY;
1314
1315 615 case JT_CONST:
1316 case JT_EQ_REF:
1317 case JT_REF_OR_NULL:
1318 case JT_REF:
1319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 615 times.
615 assert(ref().key != -1);
1320 615 return uint(ref().key);
1321
1322 2504 case JT_INDEX_SCAN:
1323 case JT_FT:
1324 2504 return index();
1325
1326 24 case JT_INDEX_MERGE:
1327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 assert(used_index(range_scan()) == MAX_KEY);
1328 24 return MAX_KEY;
1329
1330 336 case JT_RANGE:
1331 336 return used_index(range_scan());
1332
1333 7096 case JT_ALL:
1334 default:
1335 // @todo Check why JT_UNKNOWN is a valid value here.
1336
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7096 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7096 assert(type() == JT_ALL || type() == JT_UNKNOWN);
1337 7096 return MAX_KEY;
1338 }
1339 }
1340
1341 17282401 uint JOIN_TAB::get_sj_strategy() const {
1342
2/2
✓ Branch 0 taken 17215236 times.
✓ Branch 1 taken 67202 times.
17282401 if (first_sj_inner() == NO_PLAN_IDX) return SJ_OPT_NONE;
1343
3/6
✓ Branch 0 taken 67202 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 67202 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 67202 times.
✗ Branch 5 not taken.
67202 ASSERT_BEST_REF_IN_JOIN_ORDER(join());
1344 67202 JOIN_TAB *tab = join()->best_ref[first_sj_inner()];
1345 67202 uint s = tab->position()->sj_strategy;
1346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67202 times.
67202 assert(s != SJ_OPT_NONE);
1347 67202 return s;
1348 }
1349
1350 1900519 int JOIN::replace_index_subquery() {
1351
1/2
✓ Branch 0 taken 1900529 times.
✗ Branch 1 not taken.
1900519 DBUG_TRACE;
1352
3/6
✓ Branch 0 taken 1900529 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1900529 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1900529 times.
✗ Branch 5 not taken.
1900529 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
1353
1354 1900529 if (!group_list.empty() ||
1355
2/2
✓ Branch 0 taken 81230 times.
✓ Branch 1 taken 1807453 times.
1888682 !(query_expression()->item &&
1356
3/4
✓ Branch 0 taken 81230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 876 times.
✓ Branch 3 taken 80354 times.
81230 query_expression()->item->substype() == Item_subselect::IN_SUBS) ||
1357
10/10
✓ Branch 0 taken 1888682 times.
✓ Branch 1 taken 11846 times.
✓ Branch 2 taken 790 times.
✓ Branch 3 taken 86 times.
✓ Branch 4 taken 647 times.
✓ Branch 5 taken 143 times.
✓ Branch 6 taken 19 times.
✓ Branch 7 taken 627 times.
✓ Branch 8 taken 1899900 times.
✓ Branch 9 taken 628 times.
3789211 primary_tables != 1 || !where_cond || query_expression()->is_union())
1358 1899900 return 0;
1359
1360 // Guaranteed by remove_redundant_subquery_clauses():
1361
2/4
✓ Branch 0 taken 627 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 627 times.
✗ Branch 3 not taken.
628 assert(order.empty() && !select_distinct);
1362
1363 Item_in_subselect *const in_subs =
1364 627 static_cast<Item_in_subselect *>(query_expression()->item);
1365 627 bool found_engine = false;
1366
1367 627 JOIN_TAB *const first_join_tab = best_ref[0];
1368
1369
2/2
✓ Branch 0 taken 584 times.
✓ Branch 1 taken 43 times.
627 if (in_subs->strategy == Subquery_strategy::SUBQ_MATERIALIZATION) {
1370 // We cannot have two engines at the same time
1371
4/6
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 557 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
✓ Branch 4 taken 584 times.
✗ Branch 5 not taken.
611 } else if (first_join_tab->table_ref->is_view_or_derived() &&
1372 27 first_join_tab->table_ref->derived_query_expression()
1373 27 ->is_recursive()) {
1374 // The index subquery engine, which runs the derived table machinery
1375 // from the old executor, is not capable of materializing a WITH RECURSIVE
1376 // query from the iterator executor. Thus, be conservative here, so that the
1377 // case never happens.
1378
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 295 times.
584 } else if (having_cond == nullptr) {
1379 289 const join_type type = first_join_tab->type();
1380
6/6
✓ Branch 0 taken 222 times.
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 67 times.
✓ Branch 3 taken 155 times.
✓ Branch 4 taken 133 times.
✓ Branch 5 taken 156 times.
423 if ((type == JT_EQ_REF || type == JT_REF) &&
1381
2/2
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 1 times.
134 first_join_tab->ref().items[0]->item_name.ptr() == in_left_expr_name) {
1382 133 found_engine = true;
1383 }
1384 295 } else if (first_join_tab->type() == JT_REF_OR_NULL &&
1385
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 first_join_tab->ref().items[0]->item_name.ptr() ==
1386
4/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 281 times.
309 in_left_expr_name &&
1387
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
14 having_cond->created_by_in2exists()) {
1388 14 found_engine = true;
1389 }
1390
1391
2/2
✓ Branch 0 taken 480 times.
✓ Branch 1 taken 147 times.
627 if (!found_engine) return 0;
1392
1393 /* Remove redundant predicates and cache constant expressions */
1394
2/4
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 147 times.
147 if (finalize_table_conditions()) return -1;
1395
1396
2/4
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 147 times.
147 if (alloc_qep(tables)) return -1; /* purecov: inspected */
1397
1/2
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
147 unplug_join_tabs();
1398
1399 147 error = 0;
1400 147 QEP_TAB *const first_qep_tab = &qep_tab[0];
1401
1402
2/2
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 12 times.
147 if (first_qep_tab->table()->covering_keys.is_set(first_qep_tab->ref().key)) {
1403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 135 times.
135 assert(!first_qep_tab->table()->no_keyread);
1404
1/2
✓ Branch 0 taken 135 times.
✗ Branch 1 not taken.
135 first_qep_tab->table()->set_keyread(true);
1405 }
1406
1407 subselect_indexsubquery_engine *engine =
1408 147 new (thd->mem_root) subselect_indexsubquery_engine(
1409 147 first_qep_tab->table(), first_qep_tab->table_ref,
1410 147 first_qep_tab->ref(), first_qep_tab->type(),
1411 147 down_cast<Item_in_subselect *>(query_expression()->item),
1412
1/2
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
147 first_qep_tab->condition(), having_cond);
1413 147 query_expression()->item->set_indexsubquery_engine(engine);
1414 147 return 1;
1415 1900527 }
1416
1417 1900520 bool JOIN::optimize_distinct_group_order() {
1418
1/2
✓ Branch 0 taken 1900539 times.
✗ Branch 1 not taken.
1900520 DBUG_TRACE;
1419
5/6
✓ Branch 0 taken 1900538 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1900535 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1900535 times.
✗ Branch 5 not taken.
1900539 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
1420 1900536 const bool windowing = m_windows.elements > 0;
1421
2/2
✓ Branch 0 taken 1886312 times.
✓ Branch 1 taken 10229 times.
1896540 const bool may_trace = select_distinct || !group_list.empty() ||
1422
6/6
✓ Branch 0 taken 1896540 times.
✓ Branch 1 taken 3996 times.
✓ Branch 2 taken 1254629 times.
✓ Branch 3 taken 631684 times.
✓ Branch 4 taken 1253663 times.
✓ Branch 5 taken 966 times.
5050740 !order.empty() || windowing ||
1423
2/2
✓ Branch 0 taken 417389 times.
✓ Branch 1 taken 836274 times.
1253663 tmp_table_param.sum_func_count;
1424 1900538 Opt_trace_context *const trace = &thd->opt_trace;
1425
1/2
✓ Branch 0 taken 1900535 times.
✗ Branch 1 not taken.
1900538 Opt_trace_disable_I_S trace_disabled(trace, !may_trace);
1426
1/2
✓ Branch 0 taken 1900538 times.
✗ Branch 1 not taken.
1900535 Opt_trace_object wrapper(trace);
1427
1/2
✓ Branch 0 taken 1900538 times.
✗ Branch 1 not taken.
1900538 Opt_trace_object trace_opt(trace, "optimizing_distinct_group_by_order_by");
1428 /* Optimize distinct away if possible */
1429 {
1430 1900538 ORDER *org_order = order.order;
1431 1900522 order = ORDER_with_src(
1432
1/2
✓ Branch 0 taken 1900522 times.
✗ Branch 1 not taken.
1900538 remove_const(order.order, where_cond, rollup_state == RollupState::NONE,
1433 &simple_order, false),
1434 order.src);
1435
2/4
✓ Branch 0 taken 1900534 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1900534 times.
1900525 if (thd->is_error()) {
1436 error = 1;
1437 DBUG_PRINT("error", ("Error from remove_const"));
1438 return true;
1439 }
1440
1441 /*
1442 If we are using ORDER BY NULL or ORDER BY const_expression,
1443 return result in any order (even if we are using a GROUP BY)
1444 */
1445
6/6
✓ Branch 0 taken 1268201 times.
✓ Branch 1 taken 632330 times.
✓ Branch 2 taken 3671 times.
✓ Branch 3 taken 1264530 times.
✓ Branch 4 taken 3671 times.
✓ Branch 5 taken 1896860 times.
1900534 if (order.empty() && org_order) skip_sort_order = true;
1446 }
1447 /*
1448 Check if we can optimize away GROUP BY/DISTINCT.
1449 We can do that if there are no aggregate functions, the
1450 fields in DISTINCT clause (if present) and/or columns in GROUP BY
1451 (if present) contain direct references to all key parts of
1452 an unique index (in whatever order) and if the key parts of the
1453 unique index cannot contain NULLs.
1454 Note that the unique keys for DISTINCT and GROUP BY should not
1455 be the same (as long as they are unique).
1456
1457 The FROM clause must contain a single non-constant table.
1458
1459 @todo Apart from the LIS test, every condition depends only on facts
1460 which can be known in Query_block::prepare(), possibly this block should
1461 move there.
1462 */
1463
1464 1900531 JOIN_TAB *const tab = best_ref[const_tables];
1465
1466
4/4
✓ Branch 0 taken 1352289 times.
✓ Branch 1 taken 8730 times.
✓ Branch 2 taken 2966 times.
✓ Branch 3 taken 1349323 times.
3261548 if (plan_is_single_table() && (!group_list.empty() || select_distinct) &&
1467
8/8
✓ Branch 0 taken 1361017 times.
✓ Branch 1 taken 539510 times.
✓ Branch 2 taken 4120 times.
✓ Branch 3 taken 7576 times.
✓ Branch 4 taken 306 times.
✓ Branch 5 taken 3814 times.
✓ Branch 6 taken 3960 times.
✓ Branch 7 taken 1896564 times.
3265968 !tmp_table_param.sum_func_count &&
1468 4120 (!tab->range_scan() ||
1469
2/2
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 156 times.
307 tab->range_scan()->type != AccessPath::GROUP_INDEX_SKIP_SCAN)) {
1470
6/6
✓ Branch 0 taken 1083 times.
✓ Branch 1 taken 2877 times.
✓ Branch 2 taken 991 times.
✓ Branch 3 taken 92 times.
✓ Branch 4 taken 157 times.
✓ Branch 5 taken 3803 times.
4951 if (!group_list.empty() && rollup_state == RollupState::NONE &&
1471
2/2
✓ Branch 0 taken 157 times.
✓ Branch 1 taken 834 times.
991 list_contains_unique_index(tab, find_field_in_order_list,
1472
1/2
✓ Branch 0 taken 991 times.
✗ Branch 1 not taken.
991 (void *)group_list.order)) {
1473 /*
1474 We have found that grouping can be removed since groups correspond to
1475 only one row anyway.
1476 */
1477 157 group_list.clean();
1478 157 grouped = false;
1479 }
1480
4/4
✓ Branch 0 taken 2938 times.
✓ Branch 1 taken 1022 times.
✓ Branch 2 taken 185 times.
✓ Branch 3 taken 3775 times.
6898 if (select_distinct &&
1481
3/4
✓ Branch 0 taken 2938 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 185 times.
✓ Branch 3 taken 2753 times.
2938 list_contains_unique_index(tab, find_field_in_item_list, fields)) {
1482 185 select_distinct = false;
1483
1/2
✓ Branch 0 taken 185 times.
✗ Branch 1 not taken.
185 trace_opt.add("distinct_is_on_unique", true)
1484
1/2
✓ Branch 0 taken 185 times.
✗ Branch 1 not taken.
185 .add("removed_distinct", true);
1485 }
1486 }
1487
4/4
✓ Branch 0 taken 1472861 times.
✓ Branch 1 taken 417400 times.
✓ Branch 2 taken 1471794 times.
✓ Branch 3 taken 1067 times.
3790785 if (!(!group_list.empty() || tmp_table_param.sum_func_count || windowing) &&
1488
8/8
✓ Branch 0 taken 1890261 times.
✓ Branch 1 taken 10264 times.
✓ Branch 2 taken 3639 times.
✓ Branch 3 taken 1468155 times.
✓ Branch 4 taken 2803 times.
✓ Branch 5 taken 836 times.
✓ Branch 6 taken 2803 times.
✓ Branch 7 taken 1897722 times.
3793589 select_distinct && plan_is_single_table() &&
1489
1/2
✓ Branch 0 taken 2803 times.
✗ Branch 1 not taken.
2803 rollup_state == RollupState::NONE) {
1490 2803 int order_idx = -1, group_idx = -1;
1491 /*
1492 We are only using one table. In this case we change DISTINCT to a
1493 GROUP BY query if:
1494 - The GROUP BY can be done through indexes (no sort) and the ORDER
1495 BY only uses selected fields.
1496 (In this case we can later optimize away GROUP BY and ORDER BY)
1497 - We are scanning the whole table without LIMIT
1498 This can happen if:
1499 - We are using CALC_FOUND_ROWS
1500 - We are using an ORDER BY that can't be optimized away.
1501 - Selected expressions are not set functions (those cannot be put
1502 into GROUP BY).
1503
1504 We don't want to use this optimization when we are using LIMIT
1505 because in this case we can just create a temporary table that
1506 holds LIMIT rows and stop when this table is full.
1507 */
1508
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 2539 times.
2803 if (!order.empty()) {
1509 528 skip_sort_order = test_if_skip_sort_order(
1510 264 tab, order, m_select_limit,
1511 true, // no_changes
1512
1/2
✓ Branch 0 taken 264 times.
✗ Branch 1 not taken.
264 &tab->table()->keys_in_use_for_order_by, &order_idx);
1513
1/2
✓ Branch 0 taken 264 times.
✗ Branch 1 not taken.
264 count_field_types(query_block, &tmp_table_param, *fields, false, false);
1514 }
1515 ORDER *o;
1516 bool all_order_fields_used;
1517 /*
1518 There is possibility where the REF_SLICE_ACTIVE points to
1519 freed-up Items like in case of non-first row of a UPDATE
1520 trigger. Re-load the Items before using the slice.
1521 */
1522
1/2
✓ Branch 0 taken 2803 times.
✗ Branch 1 not taken.
2803 refresh_base_slice();
1523
2/2
✓ Branch 0 taken 2782 times.
✓ Branch 1 taken 21 times.
2803 if ((o = create_order_from_distinct(
1524
1/2
✓ Branch 0 taken 2803 times.
✗ Branch 1 not taken.
2803 thd, ref_items[REF_SLICE_ACTIVE], order.order, fields,
1525 /*skip_aggregates=*/true,
1526 /*convert_bit_fields_to_long=*/true, &all_order_fields_used))) {
1527 2782 group_list = ORDER_with_src(o, ESC_DISTINCT);
1528 const bool skip_group =
1529
2/2
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 2721 times.
2843 skip_sort_order &&
1530
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 10 times.
61 test_if_skip_sort_order(tab, group_list, m_select_limit,
1531 true, // no_changes
1532
1/2
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
61 &tab->table()->keys_in_use_for_group_by,
1533 2782 &group_idx);
1534
1/2
✓ Branch 0 taken 2782 times.
✗ Branch 1 not taken.
2782 count_field_types(query_block, &tmp_table_param, *fields, false, false);
1535 // ORDER BY and GROUP BY are using different indexes, can't skip sorting
1536
6/6
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 2731 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 43 times.
2782 if (group_idx >= 0 && order_idx >= 0 && group_idx != order_idx)
1537 2 skip_sort_order = false;
1538
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 49 times.
51 if ((skip_group && all_order_fields_used) ||
1539
6/6
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 2731 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 2652 times.
✓ Branch 4 taken 2730 times.
✓ Branch 5 taken 52 times.
2914 m_select_limit == HA_POS_ERROR ||
1540
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 4 times.
81 (!order.empty() && !skip_sort_order)) {
1541 /* Change DISTINCT to GROUP BY */
1542 2730 select_distinct = false;
1543 /*
1544 group_list was created with ORDER BY clause as prefix and
1545 replaces it. So it must respect ordering. If there is no
1546 ORDER BY, GROUP BY need not have to provide order.
1547 */
1548
2/2
✓ Branch 0 taken 2472 times.
✓ Branch 1 taken 258 times.
2730 if (order.empty()) {
1549
2/2
✓ Branch 0 taken 3610 times.
✓ Branch 1 taken 2472 times.
6082 for (ORDER *group = group_list.order; group; group = group->next)
1550 3610 group->direction = ORDER_NOT_RELEVANT;
1551 }
1552
8/8
✓ Branch 0 taken 2689 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 55 times.
✓ Branch 3 taken 2634 times.
✓ Branch 4 taken 43 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 43 times.
✓ Branch 7 taken 2687 times.
2730 if (all_order_fields_used && skip_sort_order && !order.empty()) {
1553 /*
1554 Force MySQL to read the table in sorted order to get result in
1555 ORDER BY order.
1556 */
1557 43 tmp_table_param.allow_group_via_temp_table = false;
1558 }
1559 2730 grouped = true; // For end_write_group
1560
1/2
✓ Branch 0 taken 2730 times.
✗ Branch 1 not taken.
2730 trace_opt.add("changed_distinct_to_group_by", true);
1561 } else
1562 52 group_list.clean();
1563
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 } else if (thd->is_fatal_error()) // End of memory
1564 return true;
1565 }
1566 1900525 simple_group = false;
1567
1568 1900525 ORDER *old_group_list = group_list.order;
1569 1900536 group_list = ORDER_with_src(
1570 remove_const(group_list.order, where_cond,
1571
1/2
✓ Branch 0 taken 1900536 times.
✗ Branch 1 not taken.
1900525 rollup_state == RollupState::NONE, &simple_group, true),
1572 group_list.src);
1573
1574
2/4
✓ Branch 0 taken 1900537 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1900537 times.
1900539 if (thd->is_error()) {
1575 error = 1;
1576 DBUG_PRINT("error", ("Error from remove_const"));
1577 return true;
1578 }
1579
6/6
✓ Branch 0 taken 12996 times.
✓ Branch 1 taken 1887541 times.
✓ Branch 2 taken 1150 times.
✓ Branch 3 taken 11846 times.
✓ Branch 4 taken 1150 times.
✓ Branch 5 taken 1899387 times.
1900537 if (old_group_list && group_list.empty()) select_distinct = false;
1580
1581
6/6
✓ Branch 0 taken 1888689 times.
✓ Branch 1 taken 11847 times.
✓ Branch 2 taken 1150 times.
✓ Branch 3 taken 1887539 times.
✓ Branch 4 taken 1150 times.
✓ Branch 5 taken 1899386 times.
1900537 if (group_list.empty() && grouped) {
1582 1150 order.clean(); // The output has only one row
1583 1150 simple_order = true;
1584 1150 select_distinct = false; // No need in distinct for 1 row
1585 1150 group_optimized_away = true;
1586 }
1587
1588
1/2
✓ Branch 0 taken 1900524 times.
✗ Branch 1 not taken.
1900536 calc_group_buffer(this, group_list.order);
1589 1900524 send_group_parts = tmp_table_param.group_parts; /* Save org parts */
1590
1591 /*
1592 If ORDER BY is a prefix of GROUP BY and if windowing or ROLLUP
1593 doesn't change this order, ORDER BY can be removed and we can
1594 enforce GROUP BY to provide order.
1595 Also true if the result is one row.
1596 */
1597
3/4
✓ Branch 0 taken 1900530 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1270204 times.
✓ Branch 3 taken 793 times.
3171521 if ((test_if_subpart(group_list.order, order.order) && !m_windows_sort &&
1598
8/8
✓ Branch 0 taken 1270997 times.
✓ Branch 1 taken 629533 times.
✓ Branch 2 taken 287 times.
✓ Branch 3 taken 1269917 times.
✓ Branch 4 taken 629699 times.
✓ Branch 5 taken 919 times.
✓ Branch 6 taken 1269918 times.
✓ Branch 7 taken 630617 times.
4431051 query_block->olap != ROLLUP_TYPE) ||
1599
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 629698 times.
1260312 (group_list.empty() && tmp_table_param.sum_func_count)) {
1600
2/2
✓ Branch 0 taken 2746 times.
✓ Branch 1 taken 1267172 times.
1269918 if (!order.empty()) {
1601 2746 order.clean();
1602
1/2
✓ Branch 0 taken 2746 times.
✗ Branch 1 not taken.
2746 trace_opt.add("removed_order_by", true);
1603 }
1604
3/4
✓ Branch 0 taken 1269904 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 400 times.
✓ Branch 3 taken 1269504 times.
1269918 if (is_indexed_agg_distinct(this, nullptr)) streaming_aggregation = false;
1605 }
1606
1607 1900521 return false;
1608 1900521 }
1609
1610 1813728 void JOIN::test_skip_sort() {
1611
1/2
✓ Branch 0 taken 1813733 times.
✗ Branch 1 not taken.
1813728 DBUG_TRACE;
1612
4/6
✓ Branch 0 taken 1813734 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1813729 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1813732 times.
✗ Branch 5 not taken.
1813733 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
1613 1813731 JOIN_TAB *const tab = best_ref[const_tables];
1614
1615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1813731 times.
1813731 assert(m_ordered_index_usage == ORDERED_INDEX_VOID);
1616
1617
2/2
✓ Branch 0 taken 11842 times.
✓ Branch 1 taken 1801890 times.
1813731 if (!group_list.empty()) // GROUP BY honoured first
1618 // (DISTINCT was rewritten to GROUP BY if skippable)
1619 {
1620 /*
1621 When there is SQL_BIG_RESULT or a JSON aggregation function,
1622 do not sort using index for GROUP BY, and thus force sorting on disk
1623 unless a group min-max optimization is going to be used as it is applied
1624 now only for one table queries with covering indexes.
1625 */
1626
8/8
✓ Branch 0 taken 11786 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11782 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 58 times.
✓ Branch 6 taken 11784 times.
✓ Branch 7 taken 58 times.
11904 if (!(query_block->active_options() & SELECT_BIG_RESULT || with_json_agg) ||
1627 60 (tab->range_scan() &&
1628
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 tab->range_scan()->type == AccessPath::GROUP_INDEX_SKIP_SCAN)) {
1629
2/2
✓ Branch 0 taken 10232 times.
✓ Branch 1 taken 1552 times.
11784 if (simple_group && // GROUP BY is possibly skippable
1630
2/2
✓ Branch 0 taken 10111 times.
✓ Branch 1 taken 121 times.
10232 !select_distinct) // .. if not preceded by a DISTINCT
1631 {
1632 /*
1633 Calculate a possible 'limit' of table rows for 'GROUP BY':
1634 A specified 'LIMIT' is relative to the final resultset.
1635 'need_tmp' implies that there will be more postprocessing
1636 so the specified 'limit' should not be enforced yet.
1637 */
1638 10111 const ha_rows limit =
1639
2/2
✓ Branch 0 taken 386 times.
✓ Branch 1 taken 9725 times.
10111 (need_tmp_before_win ? HA_POS_ERROR : m_select_limit);
1640 int dummy;
1641
1642
2/2
✓ Branch 0 taken 1478 times.
✓ Branch 1 taken 8633 times.
10111 if (test_if_skip_sort_order(tab, group_list, limit, false,
1643
1/2
✓ Branch 0 taken 10111 times.
✗ Branch 1 not taken.
10111 &tab->table()->keys_in_use_for_group_by,
1644 &dummy)) {
1645 1478 m_ordered_index_usage = ORDERED_INDEX_GROUP_BY;
1646 }
1647 }
1648
1649 /*
1650 If we are going to use semi-join LooseScan, it will depend
1651 on the selected index scan to be used. If index is not used
1652 for the GROUP BY, we risk that sorting is put on the LooseScan
1653 table. In order to avoid this, force use of temporary table.
1654 TODO: Explain the allow_group_via_temp_table part of the test below.
1655 */
1656
4/4
✓ Branch 0 taken 10306 times.
✓ Branch 1 taken 1478 times.
✓ Branch 2 taken 9484 times.
✓ Branch 3 taken 2300 times.
22090 if ((m_ordered_index_usage != ORDERED_INDEX_GROUP_BY) &&
1657
2/2
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 9484 times.
10306 (tmp_table_param.allow_group_via_temp_table ||
1658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 822 times.
822 (tab->emb_sj_nest &&
1659 tab->position()->sj_strategy == SJ_OPT_LOOSE_SCAN))) {
1660 9484 need_tmp_before_win = true;
1661 9484 simple_order = simple_group = false; // Force tmp table without sort
1662 }
1663 }
1664 1801890 } else if (!order.empty() && // ORDER BY wo/ preceding GROUP BY
1665
2/2
✓ Branch 0 taken 271598 times.
✓ Branch 1 taken 357383 times.
628981 (simple_order ||
1666
5/6
✓ Branch 0 taken 628981 times.
✓ Branch 1 taken 1172896 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 271598 times.
✓ Branch 4 taken 357322 times.
✓ Branch 5 taken 1444555 times.
2430858 skip_sort_order) && // which is possibly skippable,
1667
2/2
✓ Branch 0 taken 357322 times.
✓ Branch 1 taken 61 times.
357383 !m_windows_sort) // and WFs will not shuffle rows
1668 {
1669 int dummy;
1670
2/2
✓ Branch 0 taken 21102 times.
✓ Branch 1 taken 336220 times.
357322 if ((skip_sort_order = test_if_skip_sort_order(
1671 357322 tab, order, m_select_limit, false,
1672
1/2
✓ Branch 0 taken 357322 times.
✗ Branch 1 not taken.
357322 &tab->table()->keys_in_use_for_order_by, &dummy))) {
1673 21102 m_ordered_index_usage = ORDERED_INDEX_ORDER_BY;
1674 }
1675 }
1676 1813719 }
1677
1678 /**
1679 Test if ORDER BY is a single MATCH function(ORDER BY MATCH)
1680 and sort order is descending.
1681
1682 @param order pointer to ORDER struct.
1683
1684 @retval
1685 Pointer to MATCH function if order is 'ORDER BY MATCH() DESC'
1686 @retval
1687 NULL otherwise
1688 */
1689
1690 357828 static Item_func_match *test_if_ft_index_order(ORDER *order) {
1691
7/8
✓ Branch 0 taken 357828 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 270190 times.
✓ Branch 3 taken 87638 times.
✓ Branch 4 taken 4269 times.
✓ Branch 5 taken 265921 times.
✓ Branch 6 taken 72 times.
✓ Branch 7 taken 357756 times.
362097 if (order && order->next == nullptr && order->direction == ORDER_DESC &&
1692
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 4197 times.
4269 is_function_of_type(*order->item, Item_func::FT_FUNC))
1693 72 return down_cast<Item_func_match *>(*order->item)->get_master();
1694
1695 357756 return nullptr;
1696 }
1697
1698 /**
1699 Test if this is a prefix index.
1700
1701 @param table table
1702 @param idx index to check
1703
1704 @return TRUE if this is a prefix index
1705 */
1706 63 bool is_prefix_index(TABLE *table, uint idx) {
1707
2/4
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 63 times.
63 if (!table || !table->key_info) {
1708 return false;
1709 }
1710
1711 63 KEY *key_info = table->key_info;
1712 63 uint key_parts = key_info[idx].user_defined_key_parts;
1713 63 KEY_PART_INFO *key_part = key_info[idx].key_part;
1714
1715
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 61 times.
189 for (uint i = 0; i < key_parts; i++, key_part++) {
1716 384 if (key_part->field &&
1717
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 126 times.
128 !(table->field[key_part->fieldnr - 1]
1718
3/4
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 126 times.
256 ->part_of_prefixkey.is_clear_all()) &&
1719
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 !(key_info->flags & (HA_FULLTEXT | HA_SPATIAL))) {
1720 2 return true;
1721 }
1722 }
1723 61 return false;
1724 }
1725
1726 /**
1727 Test if one can use the key to resolve ordering.
1728
1729 @param order_src Sort order
1730 @param table Table to sort
1731 @param idx Index to check
1732 @param[out] used_key_parts NULL by default, otherwise return value for
1733 used key parts.
1734 @param[out] skip_quick Whether found index can be used for backward range
1735 scans
1736
1737 @note
1738 used_key_parts is set to correct key parts used if return value != 0
1739 (On other cases, used_key_part may be changed)
1740 Note that the value may actually be greater than the number of index
1741 key parts. This can happen for storage engines that have the primary
1742 key parts as a suffix for every secondary key.
1743
1744 @retval
1745 1 key is ok.
1746 @retval
1747 0 Key can't be used
1748 @retval
1749 -1 Reverse key can be used
1750 */
1751
1752 70260 int test_if_order_by_key(ORDER_with_src *order_src, TABLE *table, uint idx,
1753 uint *used_key_parts, bool *skip_quick) {
1754
1/2
✓ Branch 0 taken 70260 times.
✗ Branch 1 not taken.
70260 DBUG_TRACE;
1755 KEY_PART_INFO *key_part, *key_part_end;
1756 70260 key_part = table->key_info[idx].key_part;
1757 70260 key_part_end = key_part + table->key_info[idx].user_defined_key_parts;
1758 70260 key_part_map const_key_parts = table->const_key_parts[idx];
1759 70260 int reverse = 0;
1760 uint key_parts;
1761 70260 bool on_pk_suffix = false;
1762 // Whether [extended] key has key parts with mixed ASC/DESC order
1763 70260 bool mixed_order = false;
1764 // Order direction of the first key part
1765 70260 bool reverse_sorted = (bool)(key_part->key_part_flag & HA_REVERSE_SORT);
1766 70260 ORDER *order = order_src->order;
1767 70260 *skip_quick = false;
1768
1769
2/2
✓ Branch 0 taken 79959 times.
✓ Branch 1 taken 58917 times.
138876 for (; order; order = order->next, const_key_parts >>= 1) {
1770 /*
1771 Since only fields can be indexed, ORDER BY <something> that is
1772 not a field cannot be resolved by using an index.
1773 */
1774
1/2
✓ Branch 0 taken 79959 times.
✗ Branch 1 not taken.
79959 Item *real_itm = (*order->item)->real_item();
1775
3/4
✓ Branch 0 taken 79959 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 79933 times.
79959 if (real_itm->type() != Item::FIELD_ITEM) return 0;
1776
1777 79933 const Field *field = down_cast<const Item_field *>(real_itm)->field;
1778
1779 /*
1780 Skip key parts that are constants in the WHERE clause.
1781 These are already skipped in the ORDER BY by check_field_is_const()
1782 */
1783
4/4
✓ Branch 0 taken 6713 times.
✓ Branch 1 taken 79921 times.
✓ Branch 2 taken 6701 times.
✓ Branch 3 taken 12 times.
86634 for (; const_key_parts & 1 && key_part < key_part_end;
1784 6701 const_key_parts >>= 1)
1785 6701 key_part++;
1786
1787 /* Avoid usage of prefix index for sorting a partition table */
1788
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 1584 times.
✓ Branch 2 taken 63 times.
✓ Branch 3 taken 5 times.
1652 if (table->part_info && key_part != table->key_info[idx].key_part &&
1789
7/8
✓ Branch 0 taken 1652 times.
✓ Branch 1 taken 78281 times.
✓ Branch 2 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 61 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 79931 times.
81585 key_part != key_part_end && is_prefix_index(table, idx))
1790 2 return 0;
1791
1792
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 79307 times.
79931 if (key_part == key_part_end) {
1793 /*
1794 We are at the end of the key. Check if the engine has the primary
1795 key as a suffix to the secondary keys. If it has continue to check
1796 the primary key as a suffix.
1797 */
1798 1872 if (!on_pk_suffix &&
1799
2/2
✓ Branch 0 taken 605 times.
✓ Branch 1 taken 19 times.
624 (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
1800
7/8
✓ Branch 0 taken 624 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 387 times.
✓ Branch 3 taken 218 times.
✓ Branch 4 taken 332 times.
✓ Branch 5 taken 55 times.
✓ Branch 6 taken 332 times.
✓ Branch 7 taken 292 times.
1248 table->s->primary_key != MAX_KEY && table->s->primary_key != idx) {
1801 332 on_pk_suffix = true;
1802 332 key_part = table->key_info[table->s->primary_key].key_part;
1803 332 key_part_end =
1804 332 key_part +
1805 332 table->key_info[table->s->primary_key].user_defined_key_parts;
1806 332 const_key_parts = table->const_key_parts[table->s->primary_key];
1807
1808
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 332 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
341 for (; const_key_parts & 1 && key_part < key_part_end;
1809 9 const_key_parts >>= 1)
1810 9 key_part++;
1811 /*
1812 The primary and secondary key parts were all const (i.e. there's
1813 one row). The sorting doesn't matter.
1814 */
1815
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 332 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
332 if (key_part == key_part_end && reverse == 0) {
1816 key_parts = 0;
1817 reverse = 1;
1818 goto ok;
1819 }
1820 } else
1821 292 return 0;
1822 }
1823
1824
6/6
✓ Branch 0 taken 72905 times.
✓ Branch 1 taken 6734 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 72883 times.
✓ Branch 4 taken 6756 times.
✓ Branch 5 taken 72883 times.
79639 if (key_part->field != field || !field->part_of_sortkey.is_set(idx))
1825 6756 return 0;
1826
2/2
✓ Branch 0 taken 70754 times.
✓ Branch 1 taken 2129 times.
72883 if (order->direction != ORDER_NOT_RELEVANT) {
1827 70754 const enum_order keypart_order =
1828
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 70578 times.
70754 (key_part->key_part_flag & HA_REVERSE_SORT) ? ORDER_DESC : ORDER_ASC;
1829 /* set flag to 1 if we can use read-next on key, else to -1 */
1830
2/2
✓ Branch 0 taken 57306 times.
✓ Branch 1 taken 13448 times.
70754 int cur_scan_dir = (order->direction == keypart_order) ? 1 : -1;
1831
4/4
✓ Branch 0 taken 9033 times.
✓ Branch 1 taken 61721 times.
✓ Branch 2 taken 4267 times.
✓ Branch 3 taken 4766 times.
70754 if (reverse && cur_scan_dir != reverse) return 0;
1832 66487 reverse = cur_scan_dir; // Remember if reverse
1833 }
1834 68616 mixed_order |=
1835 68616 (reverse_sorted != (bool)((key_part)->key_part_flag & HA_REVERSE_SORT));
1836
1837 68616 key_part++;
1838 }
1839 /*
1840 The index picked here might be used for range scans with multiple ranges.
1841 This will require tricky reordering in case of ranges would have to be
1842 scanned backward and index consists of mixed ASC/DESC key parts. Due to that
1843 backward scans on such indexes are disabled.
1844 */
1845
4/4
✓ Branch 0 taken 165 times.
✓ Branch 1 taken 58752 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 130 times.
58917 if (mixed_order && reverse < 0) *skip_quick = true;
1846
1847
2/2
✓ Branch 0 taken 1759 times.
✓ Branch 1 taken 57158 times.
58917 if (!reverse) {
1848 /*
1849 We get here when the key is suitable and we don't care about it's
1850 order, i.e. GROUP BY/DISTINCT. Use forward scan.
1851 */
1852 1759 reverse = 1;
1853 }
1854
2/2
✓ Branch 0 taken 182 times.
✓ Branch 1 taken 58735 times.
58917 if (on_pk_suffix) {
1855 182 uint used_key_parts_secondary = table->key_info[idx].user_defined_key_parts;
1856 182 uint used_key_parts_pk =
1857 182 (uint)(key_part - table->key_info[table->s->primary_key].key_part);
1858 182 key_parts = used_key_parts_pk + used_key_parts_secondary;
1859
1860
3/4
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 182 times.
284 if (reverse == -1 &&
1861
2/4
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 102 times.
✗ Branch 3 not taken.
102 (!(table->file->index_flags(idx, used_key_parts_secondary - 1, true) &
1862 102 HA_READ_PREV) ||
1863
1/2
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
102 !(table->file->index_flags(table->s->primary_key,
1864
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
102 used_key_parts_pk - 1, true) &
1865 HA_READ_PREV)))
1866 reverse = 0; // Index can't be used
1867 } else {
1868 58735 key_parts = (uint)(key_part - table->key_info[idx].key_part);
1869
3/4
✓ Branch 0 taken 7799 times.
✓ Branch 1 taken 50936 times.
✓ Branch 2 taken 58735 times.
✗ Branch 3 not taken.
66534 if (reverse == -1 &&
1870
2/4
✓ Branch 0 taken 7799 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7799 times.
7799 !(table->file->index_flags(idx, key_parts - 1, true) & HA_READ_PREV))
1871 reverse = 0; // Index can't be used
1872 }
1873 58735 ok:
1874
2/2
✓ Branch 0 taken 57612 times.
✓ Branch 1 taken 1305 times.
58917 if (used_key_parts != nullptr) *used_key_parts = key_parts;
1875 58917 return reverse;
1876 70260 }
1877
1878 /**
1879 Find shortest key suitable for full table scan.
1880
1881 @param table Table to scan
1882 @param usable_keys Allowed keys
1883
1884 @note
1885 As far as
1886 1) clustered primary key entry data set is a set of all record
1887 fields (key fields and not key fields) and
1888 2) secondary index entry data is a union of its key fields and
1889 primary key fields (at least InnoDB and its derivatives don't
1890 duplicate primary key fields there, even if the primary and
1891 the secondary keys have a common subset of key fields),
1892 then secondary index entry data is always a subset of primary key entry.
1893 Unfortunately, key_info[nr].key_length doesn't show the length
1894 of key/pointer pair but a sum of key field lengths only, thus
1895 we can't estimate index IO volume comparing only this key_length
1896 value of secondary keys and clustered PK.
1897 So, try secondary keys first, and choose PK only if there are no
1898 usable secondary covering keys or found best secondary key include
1899 all table fields (i.e. same as PK):
1900
1901 @return
1902 MAX_KEY no suitable key found
1903 key index otherwise
1904 */
1905
1906 1816723 uint find_shortest_key(TABLE *table, const Key_map *usable_keys) {
1907 1816723 uint best = MAX_KEY;
1908 1816723 uint usable_clustered_pk = (table->file->primary_key_is_clustered() &&
1909
4/4
✓ Branch 0 taken 850565 times.
✓ Branch 1 taken 309866 times.
✓ Branch 2 taken 458322 times.
✓ Branch 3 taken 392236 times.
2010989 table->s->primary_key != MAX_KEY &&
1910 850565 usable_keys->is_set(table->s->primary_key))
1911
2/2
✓ Branch 0 taken 1160431 times.
✓ Branch 1 taken 656313 times.
2977168 ? table->s->primary_key
1912 1816737 : MAX_KEY;
1913
2/2
✓ Branch 0 taken 626570 times.
✓ Branch 1 taken 1190167 times.
1816737 if (!usable_keys->is_clear_all()) {
1914 626570 uint min_length = (uint)~0;
1915
2/2
✓ Branch 0 taken 1019163 times.
✓ Branch 1 taken 626570 times.
1645733 for (uint nr = 0; nr < table->s->keys; nr++) {
1916
2/2
✓ Branch 0 taken 458324 times.
✓ Branch 1 taken 560839 times.
1019163 if (nr == usable_clustered_pk) continue;
1917
2/2
✓ Branch 0 taken 389996 times.
✓ Branch 1 taken 170843 times.
560839 if (usable_keys->is_set(nr)) {
1918 /*
1919 Can not do full index scan on rtree index because it is not
1920 supported by Innodb, probably not supported by others either.
1921 A multi-valued key requires unique filter, and won't be the most
1922 fast option even if it will be the shortest one.
1923 */
1924 389996 const KEY &key_ref = table->key_info[nr];
1925
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 389996 times.
389996 assert(!(key_ref.flags & HA_MULTI_VALUED_KEY));
1926
4/4
✓ Branch 0 taken 383944 times.
✓ Branch 1 taken 6052 times.
✓ Branch 2 taken 382080 times.
✓ Branch 3 taken 1864 times.
389996 if (key_ref.key_length < min_length && !(key_ref.flags & HA_SPATIAL)) {
1927 382080 min_length = key_ref.key_length;
1928 382080 best = nr;
1929 }
1930 }
1931 }
1932 }
1933
2/2
✓ Branch 0 taken 458331 times.
✓ Branch 1 taken 1358406 times.
1816737 if (usable_clustered_pk != MAX_KEY) {
1934 /*
1935 If the primary key is clustered and found shorter key covers all table
1936 fields and is not clustering then primary key scan normally would be
1937 faster because amount of data to scan is the same but PK is clustered.
1938 It's safe to compare key parts with table fields since duplicate key
1939 parts aren't allowed.
1940 */
1941
4/4
✓ Branch 0 taken 213270 times.
✓ Branch 1 taken 245061 times.
✓ Branch 2 taken 245126 times.
✓ Branch 3 taken 213205 times.
671601 if (best == MAX_KEY ||
1942
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 213205 times.
213270 ((table->key_info[best].user_defined_key_parts >= table->s->fields) &&
1943
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 !(table->file->index_flags(best, 0, 0) & HA_CLUSTERED_INDEX)))
1944 245126 best = usable_clustered_pk;
1945 }
1946 1816737 return best;
1947 }
1948
1949 /**
1950 Test if a second key is the subkey of the first one.
1951
1952 @param key_part First key parts
1953 @param ref_key_part Second key parts
1954 @param ref_key_part_end Last+1 part of the second key
1955
1956 @note
1957 Second key MUST be shorter than the first one.
1958
1959 @retval
1960 1 is a subkey
1961 @retval
1962 0 no sub key
1963 */
1964
1965 554 inline bool is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part,
1966 KEY_PART_INFO *ref_key_part_end) {
1967
2/2
✓ Branch 0 taken 554 times.
✓ Branch 1 taken 349 times.
903 for (; ref_key_part < ref_key_part_end; key_part++, ref_key_part++)
1968
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 349 times.
554 if (!key_part->field->eq(ref_key_part->field)) return false;
1969 349 return true;
1970 }
1971
1972 /**
1973 Test if REF_OR_NULL optimization will be used if the specified
1974 ref_key is used for REF-access to 'tab'
1975
1976 @retval
1977 true JT_REF_OR_NULL will be used
1978 @retval
1979 false no JT_REF_OR_NULL access
1980 */
1981
1982 349 static bool is_ref_or_null_optimized(const JOIN_TAB *tab, uint ref_key) {
1983
2/2
✓ Branch 0 taken 328 times.
✓ Branch 1 taken 21 times.
349 if (tab->keyuse()) {
1984 328 const Key_use *keyuse = tab->keyuse();
1985
3/4
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 328 times.
✓ Branch 2 taken 272 times.
✗ Branch 3 not taken.
600 while (keyuse->key != ref_key && keyuse->table_ref == tab->table_ref)
1986 272 keyuse++;
1987
1988 328 const table_map const_tables = tab->join()->const_table_map;
1989
3/4
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 296 times.
✓ Branch 2 taken 360 times.
✗ Branch 3 not taken.
656 while (keyuse->key == ref_key && keyuse->table_ref == tab->table_ref) {
1990
1/2
✓ Branch 0 taken 360 times.
✗ Branch 1 not taken.
360 if (!(keyuse->used_tables & ~const_tables)) {
1991
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 328 times.
360 if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) return true;
1992 }
1993 328 keyuse++;
1994 }
1995 }
1996 317 return false;
1997 }
1998
1999 /**
2000 Test if we can use one of the 'usable_keys' instead of 'ref' key
2001 for sorting.
2002
2003 @param order The query block's order clause.
2004 @param tab Current JOIN_TAB.
2005 @param ref Number of key, used for WHERE clause
2006 @param ref_key_parts Index columns used for ref lookup.
2007 @param usable_keys Keys for testing
2008
2009 @return
2010 - MAX_KEY If we can't use other key
2011 - the number of found key Otherwise
2012 */
2013
2014 539 static uint test_if_subkey(ORDER_with_src *order, JOIN_TAB *tab, uint ref,
2015 uint ref_key_parts, const Key_map *usable_keys) {
2016 uint nr;
2017 539 uint min_length = (uint)~0;
2018 539 uint best = MAX_KEY;
2019 539 TABLE *table = tab->table();
2020 539 KEY_PART_INFO *ref_key_part = table->key_info[ref].key_part;
2021 539 KEY_PART_INFO *ref_key_part_end = ref_key_part + ref_key_parts;
2022
2023
2/2
✓ Branch 0 taken 2146 times.
✓ Branch 1 taken 539 times.
2685 for (nr = 0; nr < table->s->keys; nr++) {
2024 bool skip_quick;
2025 2146 if (usable_keys->is_set(nr) &&
2026
2/2
✓ Branch 0 taken 554 times.
✓ Branch 1 taken 2 times.
556 table->key_info[nr].key_length < min_length &&
2027
1/2
✓ Branch 0 taken 554 times.
✗ Branch 1 not taken.
554 table->key_info[nr].user_defined_key_parts >= ref_key_parts &&
2028
3/4
✓ Branch 0 taken 554 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 349 times.
✓ Branch 3 taken 205 times.
554 is_subkey(table->key_info[nr].key_part, ref_key_part,
2029 349 ref_key_part_end) &&
2030
2/2
✓ Branch 0 taken 317 times.
✓ Branch 1 taken 32 times.
349 !is_ref_or_null_optimized(tab, nr) &&
2031
7/8
✓ Branch 0 taken 556 times.
✓ Branch 1 taken 1590 times.
✓ Branch 2 taken 317 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 312 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 312 times.
✓ Branch 7 taken 1834 times.
3014 test_if_order_by_key(order, table, nr, nullptr, &skip_quick) &&
2032
1/2
✓ Branch 0 taken 312 times.
✗ Branch 1 not taken.
312 !skip_quick) {
2033 312 min_length = table->key_info[nr].key_length;
2034 312 best = nr;
2035 }
2036 }
2037 539 return best;
2038 }
2039
2040 /**
2041 It is not obvious to see that test_if_skip_sort_order() never changes the
2042 plan if no_changes is true. So we double-check: creating an instance of this
2043 class saves some important access-path-related information of the current
2044 table; when the instance is destroyed, the latest access-path information is
2045 compared with saved data.
2046 */
2047
2048 class Plan_change_watchdog {
2049 #ifndef NDEBUG
2050 public:
2051 /**
2052 @param tab_arg table whose access path is being determined
2053 @param no_changes_arg whether a change to the access path is allowed
2054 */
2055 367758 Plan_change_watchdog(const JOIN_TAB *tab_arg, const bool no_changes_arg) {
2056
2/2
✓ Branch 0 taken 325 times.
✓ Branch 1 taken 367433 times.
367758 if (no_changes_arg) {
2057 325 tab = tab_arg;
2058 325 type = tab->type();
2059
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 316 times.
325 if ((quick = tab->range_scan())) quick_index = used_index(quick);
2060 325 use_quick = tab->use_quick;
2061 325 ref_key = tab->ref().key;
2062 325 ref_key_parts = tab->ref().key_parts;
2063 325 index = tab->index();
2064 } else {
2065 367433 tab = nullptr;
2066 367433 type = JT_UNKNOWN;
2067 367433 quick = nullptr;
2068 367433 ref_key = ref_key_parts = index = 0;
2069 367433 use_quick = QS_NONE;
2070 }
2071 367758 }
2072 368083 ~Plan_change_watchdog() {
2073
2/2
✓ Branch 0 taken 367433 times.
✓ Branch 1 taken 325 times.
367758 if (tab == nullptr) return;
2074 // changes are not allowed, we verify:
2075
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 assert(tab->type() == type);
2076
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 assert(tab->range_scan() == quick);
2077
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 316 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
325 assert(quick == nullptr || used_index(tab->range_scan()) == quick_index);
2078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 assert(tab->use_quick == use_quick);
2079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 assert(tab->ref().key == ref_key);
2080
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 assert(tab->ref().key_parts == ref_key_parts);
2081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 assert(tab->index() == index);
2082 367758 }
2083
2084 private:
2085 const JOIN_TAB *tab; ///< table, or NULL if changes are allowed
2086 enum join_type type; ///< copy of tab->type()
2087 // "Range / index merge" info
2088 const AccessPath *quick{nullptr}; ///< copy of tab->select->quick
2089 uint quick_index{0}; ///< copy of tab->select->quick->index
2090 enum quick_type use_quick; ///< copy of tab->use_quick
2091 // "ref access" info
2092 int ref_key; ///< copy of tab->ref().key
2093 uint ref_key_parts; /// copy of tab->ref().key_parts
2094 // Other index-related info
2095 uint index; ///< copy of tab->index
2096 #else // in non-debug build, empty class
2097 public:
2098 Plan_change_watchdog(const JOIN_TAB *, const bool) {}
2099 #endif
2100 };
2101
2102 /**
2103 Test if we can skip ordering by using an index.
2104
2105 If the current plan is to use an index that provides ordering, the
2106 plan will not be changed. Otherwise, if an index can be used, the
2107 JOIN_TAB / tab->select struct is changed to use the index.
2108
2109 The index must cover all fields in @<order@>, or it will not be considered.
2110
2111 @param tab NULL or JOIN_TAB of the accessed table
2112 @param order Linked list of ORDER BY arguments
2113 @param select_limit LIMIT value, or HA_POS_ERROR if no limit
2114 @param no_changes No changes will be made to the query plan.
2115 @param map Key_map of applicable indexes.
2116 @param [out] order_idx Number of index selected, -1 if no applicable index
2117 found
2118
2119 @todo
2120 - sergeyp: Results of all index merge selects actually are ordered
2121 by clustered PK values.
2122
2123 @note
2124 This function may change tmp_table_param.precomputed_group_by. This
2125 affects how create_tmp_table() treats aggregation functions, so
2126 count_field_types() must be called again to make sure this is taken
2127 into consideration.
2128
2129 @retval
2130 0 We have to use filesort to do the sorting
2131 @retval
2132 1 We can use an index.
2133 */
2134
2135 367758 static bool test_if_skip_sort_order(JOIN_TAB *tab, ORDER_with_src &order,
2136 ha_rows select_limit, const bool no_changes,
2137 const Key_map *map, int *order_idx) {
2138
1/2
✓ Branch 0 taken 367758 times.
✗ Branch 1 not taken.
367758 DBUG_TRACE;
2139 int ref_key;
2140 367758 uint ref_key_parts = 0;
2141 367758 int order_direction = 0;
2142 367758 uint used_key_parts = 0;
2143 367758 TABLE *const table = tab->table();
2144 367758 JOIN *const join = tab->join();
2145 367758 THD *const thd = join->thd;
2146 367758 AccessPath *const save_range_scan = tab->range_scan();
2147 367758 int best_key = -1;
2148 367758 bool set_up_ref_access_to_key = false;
2149 367758 bool can_skip_sorting = false; // used as return value
2150 367758 int changed_key = -1;
2151
2152 /* Check that we are always called with first non-const table */
2153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 367758 times.
367758 assert((uint)tab->idx() == join->const_tables);
2154
2155 367758 Plan_change_watchdog watchdog(tab, no_changes);
2156 367758 *order_idx = -1;
2157 /* Sorting a single row can always be skipped */
2158
6/8
✓ Branch 0 taken 367758 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 367757 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 367757 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 367757 times.
735515 if (tab->type() == JT_EQ_REF || tab->type() == JT_CONST ||
2159 367757 tab->type() == JT_SYSTEM) {
2160 1 return true;
2161 }
2162
2163 /*
2164 Check if FT index can be used to retrieve result in the required order.
2165 It is possible if ordering is on the first non-constant table.
2166 */
2167
6/6
✓ Branch 0 taken 358011 times.
✓ Branch 1 taken 9746 times.
✓ Branch 2 taken 357769 times.
✓ Branch 3 taken 242 times.
✓ Branch 4 taken 357769 times.
✓ Branch 5 taken 9988 times.
367757 if (!join->order.empty() && join->simple_order) {
2168 /*
2169 Check if ORDER is DESC, ORDER BY is a single MATCH function.
2170 */
2171
1/2
✓ Branch 0 taken 357769 times.
✗ Branch 1 not taken.
357769 Item_func_match *ft_func = test_if_ft_index_order(order.order);
2172 /*
2173 Two possible cases when we can skip sort order:
2174 1. FT_SORTED must be set(Natural mode, no ORDER BY).
2175 2. If FT_SORTED flag is not set then
2176 the engine should support deferred sorting. Deferred sorting means
2177 that sorting is postponed utill the start of index reading(InnoDB).
2178 In this case we set FT_SORTED flag here to let the engine know that
2179 internal sorting is needed.
2180 */
2181
9/10
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 357718 times.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 45 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 45 times.
✓ Branch 9 taken 357724 times.
357769 if (ft_func && ft_func->ft_handler && ft_func->ordered_result()) {
2182 /*
2183 FT index scan is used, so the only additional requirement is
2184 that ORDER BY MATCH function is the same as the function that
2185 is used for FT index.
2186 */
2187
4/4
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 24 times.
71 if (tab->type() == JT_FT &&
2188
3/4
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 5 times.
26 ft_func->eq(tab->position()->key->val, true)) {
2189
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 ft_func->set_hints(join, FT_SORTED, select_limit, false);
2190 21 return true;
2191 }
2192 /*
2193 No index is used, it's possible to use FT index for ORDER BY if
2194 LIMIT is present and does not exceed count of the records in FT index
2195 and there is no WHERE condition since a condition may potentially
2196 require more rows to be fetch from FT index.
2197 */
2198
6/6
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 14 times.
36 if (!tab->condition() && select_limit != HA_POS_ERROR &&
2199
3/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 2 times.
12 select_limit <= ft_func->get_count()) {
2200 /* test_if_ft_index_order() always returns master MATCH function. */
2201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 assert(!ft_func->master);
2202 /* ref is not set since there is no WHERE condition */
2203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 assert(tab->ref().key == -1);
2204
2205 /*Make EXPLAIN happy */
2206 10 tab->set_type(JT_FT);
2207 10 tab->ref().key = ft_func->key;
2208 10 tab->ref().key_parts = 0;
2209 10 tab->set_index(ft_func->key);
2210 10 tab->set_ft_func(ft_func);
2211
2212 /* Setup FT handler */
2213
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 ft_func->set_hints(join, FT_SORTED, select_limit, true);
2214 10 ft_func->score_from_index_scan = true;
2215 10 table->file->ft_handler = ft_func->ft_handler;
2216 10 return true;
2217 }
2218 }
2219 }
2220
2221 /*
2222 Keys disabled by ALTER TABLE ... DISABLE KEYS should have already
2223 been taken into account.
2224 */
2225 367726 Key_map usable_keys = *map;
2226
2227
2/2
✓ Branch 0 taken 383868 times.
✓ Branch 1 taken 56891 times.
440759 for (ORDER *tmp_order = order.order; tmp_order; tmp_order = tmp_order->next) {
2228
1/2
✓ Branch 0 taken 383868 times.
✗ Branch 1 not taken.
383868 const Item *item = (*tmp_order->item)->real_item();
2229
3/4
✓ Branch 0 taken 383868 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3628 times.
✓ Branch 3 taken 380240 times.
383868 if (item->type() != Item::FIELD_ITEM) {
2230 3628 usable_keys.clear_all();
2231 3628 return false;
2232 }
2233 380240 usable_keys.intersect(
2234 380240 down_cast<const Item_field *>(item)->field->part_of_sortkey);
2235
2/2
✓ Branch 0 taken 307207 times.
✓ Branch 1 taken 73033 times.
380240 if (usable_keys.is_clear_all()) return false; // No usable keys
2236 }
2237
6/6
✓ Branch 0 taken 56888 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 56859 times.
✓ Branch 4 taken 32 times.
✓ Branch 5 taken 56859 times.
56891 if (tab->type() == JT_REF_OR_NULL || tab->type() == JT_FT) return false;
2238
2239 56859 ref_key = -1;
2240 /* Test if constant range in WHERE */
2241
2/2
✓ Branch 0 taken 2303 times.
✓ Branch 1 taken 54556 times.
56859 if (tab->type() == JT_REF) {
2242
2/4
✓ Branch 0 taken 2303 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2303 times.
✗ Branch 3 not taken.
2303 assert(tab->ref().key >= 0 && tab->ref().key_parts);
2243 2303 ref_key = tab->ref().key;
2244 2303 ref_key_parts = tab->ref().key_parts;
2245
6/6
✓ Branch 0 taken 47781 times.
✓ Branch 1 taken 6775 times.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 47731 times.
✓ Branch 4 taken 6825 times.
✓ Branch 5 taken 47731 times.
54556 } else if (tab->type() == JT_RANGE || tab->type() == JT_INDEX_MERGE) {
2246 // Range found by opt_range
2247 /*
2248 assume results are not ordered when index merge is used
2249 TODO: sergeyp: Results of all index merge selects actually are ordered
2250 by clustered PK values.
2251 */
2252
2253 6825 if (tab->range_scan()->type == AccessPath::INDEX_MERGE ||
2254
6/6
✓ Branch 0 taken 6795 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 6787 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 50 times.
✓ Branch 5 taken 6775 times.
13612 tab->range_scan()->type == AccessPath::ROWID_UNION ||
2255
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6775 times.
6787 tab->range_scan()->type == AccessPath::ROWID_INTERSECTION)
2256 50 return false;
2257 6775 ref_key = used_index(tab->range_scan());
2258 6775 ref_key_parts = get_used_key_parts(tab->range_scan());
2259
2/2
✓ Branch 0 taken 3641 times.
✓ Branch 1 taken 44090 times.
47731 } else if (tab->type() == JT_INDEX_SCAN) {
2260 // The optimizer has decided to use an index scan.
2261 3641 ref_key = tab->index();
2262
1/2
✓ Branch 0 taken 3641 times.
✗ Branch 1 not taken.
3641 ref_key_parts = actual_key_parts(&table->key_info[tab->index()]);
2263 }
2264
2265 56809 Opt_trace_context *const trace = &thd->opt_trace;
2266
1/2
✓ Branch 0 taken 56809 times.
✗ Branch 1 not taken.
56809 Opt_trace_object trace_wrapper_1(trace);
2267 Opt_trace_object trace_skip_sort_order(
2268
1/2
✓ Branch 0 taken 56809 times.
✗ Branch 1 not taken.
56809 trace, "reconsidering_access_paths_for_index_ordering");
2269
1/2
✓ Branch 0 taken 56809 times.
✗ Branch 1 not taken.
56809 trace_skip_sort_order.add_alnum(
2270
2/2
✓ Branch 0 taken 55192 times.
✓ Branch 1 taken 1617 times.
56809 "clause", (order.src == ESC_ORDER_BY ? "ORDER BY" : "GROUP BY"));
2271
1/2
✓ Branch 0 taken 56809 times.
✗ Branch 1 not taken.
56809 Opt_trace_array trace_steps(trace, "steps");
2272
2273
2/2
✓ Branch 0 taken 12719 times.
✓ Branch 1 taken 44090 times.
56809 if (ref_key >= 0) {
2274 /*
2275 We come here when ref/index scan/range scan access has been set
2276 up for this table. Do not change access method if ordering is
2277 provided already.
2278 */
2279
2/2
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 12180 times.
12719 if (!usable_keys.is_set(ref_key)) {
2280 /*
2281 We come here when ref_key is not among usable_keys, try to find a
2282 usable prefix key of that key.
2283 */
2284 uint new_ref_key;
2285 /*
2286 If using index only read, only consider other possible index only
2287 keys
2288 */
2289
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 538 times.
539 if (table->covering_keys.is_set(ref_key))
2290 1 usable_keys.intersect(table->covering_keys);
2291
2292
1/2
✓ Branch 0 taken 539 times.
✗ Branch 1 not taken.
539 if ((new_ref_key = test_if_subkey(&order, tab, ref_key, ref_key_parts,
2293
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 227 times.
539 &usable_keys)) < MAX_KEY) {
2294 /* Found key that can be used to retrieve data in sorted order */
2295
2/2
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 16 times.
312 if (tab->ref().key >= 0) {
2296 /*
2297 We'll use ref access method on key new_ref_key. The actual change
2298 is done further down in this function where we update the plan.
2299 */
2300 296 set_up_ref_access_to_key = true;
2301
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 } else if (!no_changes) {
2302 /*
2303 The range optimizer constructed QUICK_RANGE for ref_key, and
2304 we want to use instead new_ref_key as the index. We can't
2305 just change the index of the quick select, because this may
2306 result in an inconsistent RowIterator object. Below we
2307 create a new RowIterator from scratch so that all its
2308 parameres are set correctly by the range optimizer.
2309
2310 Note that the range optimizer is NOT called if
2311 no_changes==true. This reason is that the range optimizer
2312 cannot find a QUICK that can return ordered result unless
2313 index access (ref or index scan) is also able to do so
2314 (which test_if_order_by_key () will tell).
2315 Admittedly, range access may be much more efficient than
2316 e.g. index scan, but the only thing that matters when
2317 no_change==true is the answer to the question: "Is it
2318 possible to avoid sorting if an index is used to access
2319 this table?". The answer does not depend on the outcome of
2320 the range optimizer.
2321 */
2322
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 Key_map new_ref_key_map; // Force the creation of quick select
2323 14 new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
2324
2325
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 Opt_trace_object trace_wrapper_2(trace);
2326
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 Opt_trace_object trace_recest(trace, "rows_estimation");
2327
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 trace_recest.add_utf8_table(tab->table_ref)
2328
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 .add_utf8("index", table->key_info[new_ref_key].name);
2329 AccessPath *range_scan;
2330 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
2331 14 thd->variables.range_alloc_block_size);
2332 const bool no_quick =
2333
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
28 test_quick_select(
2334 thd, thd->mem_root, &temp_mem_root, new_ref_key_map, 0,
2335 0, // empty table_map
2336 14 join->calc_found_rows
2337 ? HA_POS_ERROR
2338 14 : join->query_expression()->select_limit_cnt,
2339 false, // don't force quick range
2340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 order.order->direction, tab->table(),
2341 14 tab->skip_records_in_range(),
2342 // we are after make_join_query_block():
2343 14 tab->condition(), &tab->needed_reg, tab->table()->force_index,
2344 14 join->query_block, &range_scan) <= 0;
2345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 assert(tab->range_scan() == save_range_scan);
2346 14 tab->set_range_scan(range_scan);
2347
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
14 if (no_quick) {
2348 3 can_skip_sorting = false;
2349 3 goto fix_ICP;
2350 }
2351
6/6
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 3 times.
20 }
2352 309 ref_key = new_ref_key;
2353 309 changed_key = new_ref_key;
2354 }
2355 }
2356 bool dummy;
2357 /* Check if we get the rows in requested sorted order by using the key */
2358
2/2
✓ Branch 0 taken 12489 times.
✓ Branch 1 taken 227 times.
12716 if (usable_keys.is_set(ref_key))
2359 // Last parameter can be ignored as it'll be checked later, if needed
2360 order_direction =
2361
1/2
✓ Branch 0 taken 12489 times.
✗ Branch 1 not taken.
12489 test_if_order_by_key(&order, table, ref_key, &used_key_parts, &dummy);
2362 }
2363
4/4
✓ Branch 0 taken 12716 times.
✓ Branch 1 taken 44090 times.
✓ Branch 2 taken 5725 times.
✓ Branch 3 taken 6991 times.
56806 if (ref_key < 0 || order_direction <= 0) {
2364 /*
2365 There is no ref/index scan/range scan access set up for this
2366 table, or it does not provide the requested ordering, or it uses
2367 backward scan. Do a cost-based search on all keys.
2368 */
2369 49815 uint best_key_parts = 0;
2370 49815 uint saved_best_key_parts = 0;
2371 49815 int best_key_direction = 0;
2372 49815 ha_rows table_records = table->file->stats.records;
2373
2374 /*
2375 If an index scan that cannot provide ordering has been selected
2376 then do not use the index scan key as starting hint to
2377 test_if_cheaper_ordering()
2378 */
2379 const int ref_key_hint =
2380
4/4
✓ Branch 0 taken 47060 times.
✓ Branch 1 taken 2755 times.
✓ Branch 2 taken 45862 times.
✓ Branch 3 taken 1198 times.
49815 (order_direction == 0 && tab->type() == JT_INDEX_SCAN) ? -1 : ref_key;
2381
2382 // Does the query have a "FORCE INDEX [FOR GROUP BY] (idx)" (if clause is
2383 // group by) or a "FORCE INDEX [FOR ORDER BY] (idx)" (if clause is order
2384 // by)?
2385 49815 const bool is_group_by =
2386
4/6
✓ Branch 0 taken 49815 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 329 times.
✓ Branch 3 taken 49486 times.
✓ Branch 4 taken 329 times.
✗ Branch 5 not taken.
49815 join && join->grouped && order.order == join->group_list.order;
2387 49815 const bool is_force_index =
2388
4/4
✓ Branch 0 taken 48959 times.
✓ Branch 1 taken 856 times.
✓ Branch 2 taken 317 times.
✓ Branch 3 taken 48642 times.
98774 table->force_index ||
2389
4/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 315 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 48639 times.
48959 (is_group_by ? table->force_index_group : table->force_index_order);
2390
2391 // Find an ordering index alternative over the chosen plan iff
2392 // prefer_ordering_index switch is on. This switch is overridden only when
2393 // force index for order/group is specified.
2394
6/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 49805 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 49807 times.
✓ Branch 5 taken 8 times.
49815 if (thd->optimizer_switch_flag(OPTIMIZER_SWITCH_PREFER_ORDERING_INDEX) ||
2395 is_force_index)
2396
1/2
✓ Branch 0 taken 49807 times.
✗ Branch 1 not taken.
49807 test_if_cheaper_ordering(tab, &order, table, usable_keys, ref_key_hint,
2397 select_limit, &best_key, &best_key_direction,
2398 &select_limit, &best_key_parts,
2399 &saved_best_key_parts);
2400
2401 // Try backward scan for previously found key
2402
4/4
✓ Branch 0 taken 36871 times.
✓ Branch 1 taken 12944 times.
✓ Branch 2 taken 2743 times.
✓ Branch 3 taken 34128 times.
49815 if (best_key < 0 && order_direction < 0) goto check_reverse_order;
2403
2404
2/2
✓ Branch 0 taken 34128 times.
✓ Branch 1 taken 12944 times.
47072 if (best_key < 0) {
2405 // No usable key has been found
2406 34128 can_skip_sorting = false;
2407 34150 goto fix_ICP;
2408 }
2409 /*
2410 If found index will use backward index scan, ref_key uses backward
2411 range/ref, pick the latter as it has better selectivity.
2412 */
2413
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12932 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12944 if (order_direction < 0 && order_direction == best_key_direction) {
2414 best_key = -1; // reset found best key
2415 goto check_reverse_order;
2416 }
2417
2418 /*
2419 filesort() and join cache are usually faster than reading in
2420 index order and not using join cache. Don't use index scan
2421 unless:
2422 - the user specified FORCE INDEX [FOR {GROUP|ORDER} BY] (have to assume
2423 the user knows what's best)
2424 - the chosen index is clustered primary key (table scan is not cheaper)
2425 */
2426
4/4
✓ Branch 0 taken 9537 times.
✓ Branch 1 taken 3331 times.
✓ Branch 2 taken 8628 times.
✓ Branch 3 taken 909 times.
22405 if (!is_force_index && (select_limit >= table_records) &&
2427 9537 (tab->type() == JT_ALL &&
2428
6/6
✓ Branch 0 taken 12868 times.
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 8557 times.
✓ Branch 4 taken 22 times.
✓ Branch 5 taken 12922 times.
25883 join->primary_tables > join->const_tables + 1) &&
2429
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 19 times.
71 ((unsigned)best_key != table->s->primary_key ||
2430
3/4
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 49 times.
52 !table->file->primary_key_is_clustered())) {
2431 22 can_skip_sorting = false;
2432 22 goto fix_ICP;
2433 }
2434
2435 12922 if (table->quick_keys.is_set(best_key) &&
2436
6/8
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 12820 times.
✓ Branch 2 taken 102 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 102 times.
✓ Branch 7 taken 12820 times.
12922 !tab->quick_order_tested.is_set(best_key) && best_key != ref_key) {
2437 102 tab->quick_order_tested.set_bit(best_key);
2438
1/2
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
102 Opt_trace_object trace_wrapper_3(trace);
2439
1/2
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
102 Opt_trace_object trace_recest(trace, "rows_estimation");
2440
1/2
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
102 trace_recest.add_utf8_table(tab->table_ref)
2441
1/2
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
102 .add_utf8("index", table->key_info[best_key].name);
2442
2443
1/2
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
102 Key_map keys_to_use; // Force the creation of quick select
2444 102 keys_to_use.set_bit(best_key); // only best_key.
2445 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
2446 102 thd->variables.range_alloc_block_size);
2447 AccessPath *range_scan;
2448
1/2
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
204 test_quick_select(
2449 thd, thd->mem_root, &temp_mem_root, keys_to_use, 0,
2450 0, // empty table_map
2451 102 join->calc_found_rows ? HA_POS_ERROR
2452 102 : join->query_expression()->select_limit_cnt,
2453 true, // force quick range
2454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
204 order.order->direction, tab->table(), tab->skip_records_in_range(),
2455 102 tab->condition(), &tab->needed_reg, tab->table()->force_index,
2456 102 join->query_block, &range_scan);
2457
6/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 100 times.
104 if (order_direction < 0 && tab->range_scan() != nullptr &&
2458 2 tab->range_scan() != save_range_scan) {
2459 /*
2460 We came here in case when 3 indexes are available for quick
2461 select:
2462 1 - found by join order optimizer (greedy search) and saved in
2463 save_range_scan
2464 2 - constructed far above, as better suited for order by, but it was
2465 found that it requires backward scan.
2466 3 - constructed right above
2467 In this case we drop quick #2 as #3 is expected to be better.
2468 */
2469 2 destroy(tab->range_scan());
2470 2 tab->set_range_scan(nullptr);
2471 }
2472 /*
2473 If tab->range_scan() pointed to another quick than save_range_scan, we
2474 would lose access to it and leak memory.
2475 */
2476
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
102 assert(tab->range_scan() == save_range_scan ||
2477 tab->range_scan() == nullptr);
2478 102 tab->set_range_scan(range_scan);
2479
6/6
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 78 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 78 times.
✓ Branch 5 taken 24 times.
102 if (tab->range_scan() && !no_changes)
2480
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 tab->set_type(calc_join_type(tab->range_scan()));
2481 102 }
2482 12922 order_direction = best_key_direction;
2483 /*
2484 saved_best_key_parts is actual number of used keyparts found by the
2485 test_if_order_by_key function. It could differ from keyinfo->key_parts,
2486 thus we have to restore it in case of desc order as it affects
2487 ReverseIndexRangeScanIterator behaviour.
2488 */
2489 12922 used_key_parts =
2490
2/2
✓ Branch 0 taken 1411 times.
✓ Branch 1 taken 11511 times.
12922 (order_direction == -1) ? saved_best_key_parts : best_key_parts;
2491 12922 changed_key = best_key;
2492 // We will use index scan or range scan:
2493 12922 set_up_ref_access_to_key = false;
2494 }
2495
2496 6991 check_reverse_order:
2497
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22656 times.
22656 assert(order_direction != 0);
2498
2499
2/2
✓ Branch 0 taken 4154 times.
✓ Branch 1 taken 18502 times.
22656 if (order_direction == -1) // If ORDER BY ... DESC
2500 {
2501
2/2
✓ Branch 0 taken 1639 times.
✓ Branch 1 taken 2515 times.
4154 if (tab->range_scan()) {
2502 /*
2503 Don't reverse the sort order, if it's already done.
2504 (In some cases test_if_order_by_key() can be called multiple times
2505 */
2506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1639 times.
1639 if (is_reverse_sorted_range(tab->range_scan())) {
2507 can_skip_sorting = true;
2508 goto fix_ICP;
2509 }
2510 // test_if_cheaper_ordering() might disable range scan on current index
2511
5/6
✓ Branch 0 taken 1633 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1633 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1633 times.
✓ Branch 5 taken 6 times.
3272 if (tab->table()->quick_keys.is_set(used_index(tab->range_scan())) &&
2512 1633 reverse_sort_possible(tab->range_scan()))
2513 1633 can_skip_sorting = true;
2514 else {
2515 6 can_skip_sorting = false;
2516 6 goto fix_ICP;
2517 }
2518 } else {
2519 // Other index access (ref or scan) poses no problem
2520 2515 can_skip_sorting = true;
2521 }
2522 } else {
2523 // ORDER BY ASC poses no problem
2524 18502 can_skip_sorting = true;
2525 }
2526
2527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22650 times.
22650 assert(can_skip_sorting);
2528
2529 /*
2530 Update query plan with access pattern for doing
2531 ordered access according to what we have decided
2532 above.
2533 */
2534
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 22548 times.
22650 if (!no_changes) // We are allowed to update QEP
2535 {
2536
2/2
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 22264 times.
22548 if (set_up_ref_access_to_key) {
2537 /*
2538 We'll use ref access method on key changed_key. In general case
2539 the index search tuple for changed_ref_key will be different (e.g.
2540 when one index is defined as (part1, part2, ...) and another as
2541 (part1, part2(N), ...) and the WHERE clause contains
2542 "part1 = const1 AND part2=const2".
2543 So we build tab->ref() from scratch here.
2544 */
2545 284 Key_use *keyuse = tab->keyuse();
2546
2/2
✓ Branch 0 taken 260 times.
✓ Branch 1 taken 284 times.
544 while (keyuse->key != (uint)changed_key &&
2547
1/2
✓ Branch 0 taken 260 times.
✗ Branch 1 not taken.
260 keyuse->table_ref == tab->table_ref)
2548 260 keyuse++;
2549
2550
2/4
✓ Branch 0 taken 284 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 284 times.
284 if (create_ref_for_key(join, tab, keyuse, tab->prefix_tables())) {
2551 can_skip_sorting = false;
2552 goto fix_ICP;
2553 }
2554
2555
2/4
✓ Branch 0 taken 284 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 284 times.
✗ Branch 3 not taken.
284 assert(tab->type() != JT_REF_OR_NULL && tab->type() != JT_FT);
2556
2557 // Changing the key makes filter_effect obsolete
2558 284 tab->position()->filter_effect = COND_FILTER_STALE;
2559
2560 /*
2561 Check if it is possible to shift from ref to range. The index chosen
2562 for 'ref' has changed since the last time this function was called.
2563 */
2564
3/4
✓ Branch 0 taken 284 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 260 times.
284 if (can_switch_from_ref_to_range(thd, tab, order.order->direction,
2565 true)) {
2566 // Allow the code to fall-through to the next if condition.
2567 24 set_up_ref_access_to_key = false;
2568 24 best_key = changed_key;
2569 }
2570 }
2571
4/4
✓ Branch 0 taken 22288 times.
✓ Branch 1 taken 260 times.
✓ Branch 2 taken 12936 times.
✓ Branch 3 taken 9352 times.
22548 if (!set_up_ref_access_to_key && best_key >= 0) {
2572 // Cancel any ref-access previously set up
2573 12936 tab->ref().key = -1;
2574 12936 tab->ref().key_parts = 0;
2575
2576 /*
2577 If ref_key used index tree reading only ('Using index' in EXPLAIN),
2578 and best_key doesn't, then revert the decision.
2579 */
2580
3/4
✓ Branch 0 taken 12864 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 12864 times.
✗ Branch 3 not taken.
12936 if (!table->covering_keys.is_set(best_key)) table->set_keyread(false);
2581 // Create an index scan if the table is not a temporary table that uses
2582 // Temptable engine (Does not support index_first() and index_last()) and
2583 // if there was no new range scan created.
2584 12936 if (!(is_temporary_table(tab->table_ref) &&
2585
8/10
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 12857 times.
✓ Branch 2 taken 79 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 79 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 188 times.
✓ Branch 7 taken 12748 times.
✓ Branch 8 taken 12834 times.
✓ Branch 9 taken 102 times.
26060 tab->table_ref->table->s->db_type() == temptable_hton) &&
2586
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 102 times.
13124 ((!tab->range_scan() || tab->range_scan() == save_range_scan))) {
2587 // Avoid memory leak:
2588
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12834 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12834 assert(tab->range_scan() == save_range_scan ||
2589 tab->range_scan() == nullptr);
2590 12834 tab->set_range_scan(nullptr);
2591 12834 tab->set_index(best_key);
2592 12834 tab->set_type(JT_INDEX_SCAN); // Read with index_first(), index_next()
2593 /*
2594 There is a bug. When we change here, e.g. from group_min_max to
2595 index scan: loose index scan expected to read a small number of rows
2596 (jumping through the index), this small number was in
2597 position()->rows_fetched; index scan will read much more, so
2598 rows_fetched should be updated. So should the filtering effect.
2599 It is visible in main.distinct in trunk:
2600 explain SELECT distinct a from t3 order by a desc limit 2;
2601 id select_type table partitions type
2602 possible_keys key key_len ref rows filtered Extra 1
2603 SIMPLE t3 NULL index a a 5 NULL
2604 40 25.00 Using index "rows=40" should be ~200 i.e. # of records
2605 in table. Filter should be 100.00 (no WHERE).
2606 */
2607
1/2
✓ Branch 0 taken 12834 times.
✗ Branch 1 not taken.
12834 table->file->ha_index_or_rnd_end();
2608 12834 tab->position()->filter_effect = COND_FILTER_STALE;
2609
1/2
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
102 } else if (tab->type() != JT_ALL) {
2610 /*
2611 We're about to use a quick access to the table.
2612 We need to change the access method so as the quick access
2613 method is actually used.
2614 */
2615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
102 assert(tab->range_scan());
2616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
102 assert(used_index(tab->range_scan()) == (uint)best_key);
2617
1/2
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
102 tab->set_type(calc_join_type(tab->range_scan()));
2618 102 tab->use_quick = QS_RANGE;
2619
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
102 if (is_loose_index_scan(tab->range_scan()))
2620 join->tmp_table_param.precomputed_group_by = true;
2621 102 tab->position()->filter_effect = COND_FILTER_STALE;
2622 }
2623 } // best_key >= 0
2624
2625
2/2
✓ Branch 0 taken 4126 times.
✓ Branch 1 taken 18422 times.
22548 if (order_direction == -1) // If ORDER BY ... DESC
2626 {
2627
2/2
✓ Branch 0 taken 1603 times.
✓ Branch 1 taken 2523 times.
4126 if (tab->range_scan()) {
2628 /* ORDER BY range_key DESC */
2629
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1603 times.
1603 if (make_reverse(used_key_parts, tab->range_scan())) {
2630 /* purecov: begin inspected */
2631 can_skip_sorting = false; // Reverse sort failed -> filesort
2632 goto fix_ICP;
2633 /* purecov: end */
2634 }
2635
1/2
✓ Branch 0 taken 1603 times.
✗ Branch 1 not taken.
1603 tab->set_type(calc_join_type(tab->range_scan()));
2636 1603 tab->position()->filter_effect = COND_FILTER_STALE;
2637
4/4
✓ Branch 0 taken 854 times.
✓ Branch 1 taken 1669 times.
✓ Branch 2 taken 854 times.
✓ Branch 3 taken 1669 times.
3377 } else if (tab->type() == JT_REF &&
2638
1/2
✓ Branch 0 taken 854 times.
✗ Branch 1 not taken.
854 tab->ref().key_parts <= used_key_parts) {
2639 /*
2640 SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
2641
2642 Use a traversal function that starts by reading the last row
2643 with key part (A) and then traverse the index backwards.
2644 */
2645 854 tab->reversed_access = true;
2646
2647 /*
2648 The current implementation of the reverse RefIterator does not
2649 work well in combination with ICP and can lead to increased
2650 execution time. Setting changed_key to the current key
2651 (based on that we change the access order for the key) will
2652 ensure that a pushed index condition will be cancelled.
2653 */
2654 854 changed_key = tab->ref().key;
2655
1/2
✓ Branch 0 taken 1669 times.
✗ Branch 1 not taken.
1669 } else if (tab->type() == JT_INDEX_SCAN)
2656 1669 tab->reversed_access = true;
2657
2/2
✓ Branch 0 taken 3994 times.
✓ Branch 1 taken 14428 times.
18422 } else if (tab->range_scan())
2658 3994 set_need_sorted_output(tab->range_scan());
2659
2660 } // QEP has been modified
2661
2662 102 fix_ICP:
2663 /*
2664 Cleanup:
2665 We may have both a 'tab->range_scan()' and 'save_range_scan' (original)
2666 at this point. Delete the one that we won't use.
2667 */
2668
4/4
✓ Branch 0 taken 22650 times.
✓ Branch 1 taken 34159 times.
✓ Branch 2 taken 22548 times.
✓ Branch 3 taken 102 times.
56809 if (can_skip_sorting && !no_changes) {
2669
4/4
✓ Branch 0 taken 15188 times.
✓ Branch 1 taken 7360 times.
✓ Branch 2 taken 3387 times.
✓ Branch 3 taken 19161 times.
37736 if (tab->type() == JT_INDEX_SCAN &&
2670
2/2
✓ Branch 0 taken 3387 times.
✓ Branch 1 taken 11801 times.
15188 select_limit < table->file->stats.records) {
2671
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3387 times.
3387 assert(select_limit > 0);
2672 3387 tab->position()->rows_fetched = select_limit;
2673 3387 tab->position()->filter_effect = COND_FILTER_STALE_NO_CONST;
2674 }
2675
2676 // Keep current (ordered) tab->range_scan()
2677
2/2
✓ Branch 0 taken 197 times.
✓ Branch 1 taken 22351 times.
22548 if (save_range_scan != tab->range_scan()) destroy(save_range_scan);
2678 } else {
2679 // Restore original save_range_scan
2680
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 34257 times.
34261 if (tab->range_scan() != save_range_scan) {
2681 4 destroy(tab->range_scan());
2682 4 tab->set_range_scan(save_range_scan);
2683 }
2684 }
2685
2686
1/2
✓ Branch 0 taken 56809 times.
✗ Branch 1 not taken.
56809 trace_steps.end();
2687
1/2
✓ Branch 0 taken 56809 times.
✗ Branch 1 not taken.
56809 Opt_trace_object trace_change_index(trace, "index_order_summary");
2688
1/2
✓ Branch 0 taken 56809 times.
✗ Branch 1 not taken.
56809 trace_change_index.add_utf8_table(tab->table_ref)
2689
1/2
✓ Branch 0 taken 56809 times.
✗ Branch 1 not taken.
56809 .add("index_provides_order", can_skip_sorting)
2690
3/4
✓ Branch 0 taken 38307 times.
✓ Branch 1 taken 18502 times.
✓ Branch 2 taken 56809 times.
✗ Branch 3 not taken.
95116 .add_alnum("order_direction",
2691 order_direction == 1
2692 ? "asc"
2693
2/2
✓ Branch 0 taken 4154 times.
✓ Branch 1 taken 34153 times.
38307 : ((order_direction == -1) ? "desc" : "undefined"));
2694
2695
2/2
✓ Branch 0 taken 14083 times.
✓ Branch 1 taken 42726 times.
56809 if (changed_key >= 0) {
2696 // switching to another index
2697 // Should be no pushed index conditions at this point
2698
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14083 times.
14083 assert(!table->file->pushed_idx_cond);
2699
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 14043 times.
14083 if (unlikely(trace->is_started())) {
2700
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 trace_change_index.add_utf8("index", table->key_info[changed_key].name);
2701
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 trace_change_index.add("plan_changed", !no_changes);
2702
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 if (!no_changes)
2703
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 trace_change_index.add_alnum("access_type", join_type_str[tab->type()]);
2704 }
2705
2/2
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 42645 times.
42726 } else if (unlikely(trace->is_started())) {
2706
2/4
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✗ Branch 3 not taken.
162 trace_change_index.add_utf8(
2707 81 "index", ref_key >= 0 ? table->key_info[ref_key].name : "unknown");
2708
1/2
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
81 trace_change_index.add("plan_changed", false);
2709 }
2710
2/2
✓ Branch 0 taken 43841 times.
✓ Branch 1 taken 12968 times.
56809 *order_idx = best_key < 0 ? ref_key : best_key;
2711 56809 return can_skip_sorting;
2712 367758 }
2713
2714 /**
2715 Prune partitions for all tables of a join (query block).
2716
2717 Requires that tables have been locked.
2718
2719 @returns false if success, true if error
2720 */
2721
2722 19627 bool JOIN::prune_table_partitions() {
2723
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19627 times.
19627 assert(query_block->partitioned_table_count);
2724
2725
2/2
✓ Branch 0 taken 20186 times.
✓ Branch 1 taken 19624 times.
39810 for (TABLE_LIST *tbl = query_block->leaf_tables; tbl; tbl = tbl->next_leaf) {
2726 // This will try to prune non-static conditions, which can be probed after
2727 // the tables are locked.
2728
2729 // Predicates for pruning of this table must be placed in the outer-most
2730 // join nest (Predicates in other join nests, or in the WHERE clause,
2731 // would have caused an outer join to be converted to an inner join,
2732 // and thus there would be no join nest graph to traverse)
2733 // Look up the join nest hierarchy for the outermost condition:
2734 20186 Item *cond = where_cond;
2735 20186 const table_map tbl_map = tbl->map();
2736
2/2
✓ Branch 0 taken 20413 times.
✓ Branch 1 taken 20166 times.
40579 for (TABLE_LIST *nest = tbl; nest != nullptr; nest = nest->embedding) {
2737
6/6
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 20103 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 265 times.
✓ Branch 5 taken 20148 times.
20723 if (nest->join_cond_optim() != nullptr &&
2738 310 Overlaps(tbl_map, nest->join_cond_optim()->used_tables())) {
2739 265 cond = nest->join_cond_optim();
2740 // For an anti-join operation, a synthetic left join nest is added above
2741 // the anti-join nest. Make sure that we skip this when searching for
2742 // the predicate to prune.
2743
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 245 times.
265 if (nest->is_aj_nest()) break;
2744 }
2745 }
2746
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 20183 times.
20186 if (prune_partitions(thd, tbl->table, query_block, cond)) {
2747 3 return true;
2748 }
2749 }
2750
2751 19624 return false;
2752 }
2753
2754 /**
2755 A helper function to check whether it's better to use range than ref.
2756
2757 @details
2758 Heuristic: Switch from 'ref' to 'range' access if 'range'
2759 access can utilize more keyparts than 'ref' access. Conditions
2760 for doing switching:
2761
2762 1) Range access is possible
2763 2) 'ref' access and 'range' access uses the same index
2764 3) Used parts of key shouldn't have nullable parts & ref_or_null isn't used.
2765 4) 'ref' access depends on a constant, not a value read from a
2766 table earlier in the join sequence.
2767
2768 Rationale: if 'ref' depends on a value from another table,
2769 the join condition is not used to limit the rows read by
2770 'range' access (that would require dynamic range - 'Range
2771 checked for each record'). In other words, if 'ref' depends
2772 on a value from another table, we have a query with
2773 conditions of the form
2774
2775 this_table.idx_col1 = other_table.col AND <<- used by 'ref'
2776 this_table.idx_col1 OP @<const@> AND <<- used by 'range'
2777 this_table.idx_col2 OP @<const@> AND ... <<- used by 'range'
2778
2779 and an index on (idx_col1,idx_col2,...). But the fact that
2780 'range' access uses more keyparts does not mean that it is
2781 more selective than 'ref' access because these access types
2782 utilize different parts of the query condition. We
2783 therefore trust the cost based choice made by
2784 best_access_path() instead of forcing a heuristic choice
2785 here.
2786 5) 'range' access uses more keyparts than 'ref' access
2787 6) ORDER BY might make range better than table scan:
2788 Check possibility of range scan even if it was previously deemed unviable
2789 (for example when table scan was estimated to be cheaper). If yes,
2790 range-access should be chosen only for larger key length.
2791
2792 @param thd To re-run range optimizer.
2793 @param tab JOIN_TAB to check
2794 @param ordering Used as a parameter to call test_quick_select.
2795 @param recheck_range Check possibility of range scan even if it is currently
2796 unviable.
2797
2798 @return true Range is better than ref
2799 @return false Ref is better or switch isn't possible
2800
2801 @todo: This decision should rather be made in best_access_path()
2802 */
2803
2804 2022958 static bool can_switch_from_ref_to_range(THD *thd, JOIN_TAB *tab,
2805 enum_order ordering,
2806 bool recheck_range) {
2807
2/2
✓ Branch 0 taken 4260 times.
✓ Branch 1 taken 213979 times.
2241197 if ((tab->range_scan() && // 1)
2808
6/6
✓ Branch 0 taken 218239 times.
✓ Branch 1 taken 1804736 times.
✓ Branch 2 taken 284 times.
✓ Branch 3 taken 1808712 times.
✓ Branch 4 taken 214263 times.
✓ Branch 5 taken 1808712 times.
2241214 tab->position()->key->key == used_index(tab->range_scan())) || // 2)
2809 recheck_range) {
2810 214263 uint keyparts = 0, length = 0;
2811 214263 table_map dep_map = 0;
2812 214263 bool maybe_null = false;
2813
2814
1/2
✓ Branch 0 taken 214263 times.
✗ Branch 1 not taken.
428526 calc_length_and_keyparts(tab->position()->key, tab,
2815 214263 tab->position()->key->key, tab->prefix_tables(),
2816 nullptr, &length, &keyparts, &dep_map,
2817 &maybe_null);
2818
2/2
✓ Branch 0 taken 214172 times.
✓ Branch 1 taken 91 times.
214263 if (!maybe_null && // 3)
2819
2/2
✓ Branch 0 taken 75896 times.
✓ Branch 1 taken 138276 times.
214172 !dep_map) // 4)
2820 {
2821
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 75859 times.
75896 if (recheck_range) // 6)
2822 {
2823
1/2
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
37 Key_map new_ref_key_map;
2824 37 new_ref_key_map.set_bit(tab->ref().key);
2825
2826 37 Opt_trace_context *const trace = &thd->opt_trace;
2827
1/2
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
37 Opt_trace_object trace_wrapper(trace);
2828 Opt_trace_object can_switch(
2829
1/2
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
37 trace, "check_if_range_uses_more_keyparts_than_ref");
2830 Opt_trace_object trace_cond(
2831
1/2
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
37 trace, "rerunning_range_optimizer_for_single_index");
2832
2833 AccessPath *range_scan;
2834 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
2835 37 thd->variables.range_alloc_block_size);
2836
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
148 if (test_quick_select(
2837 thd, thd->mem_root, &temp_mem_root, new_ref_key_map, 0,
2838 0, // empty table_map
2839 37 tab->join()->row_limit, false, ordering, tab->table(),
2840 37 tab->skip_records_in_range(),
2841 37 tab->join_cond() ? tab->join_cond() : tab->join()->where_cond,
2842 37 &tab->needed_reg, recheck_range, tab->join()->query_block,
2843
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 6 times.
37 &range_scan) > 0) {
2844
3/4
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 7 times.
31 if (length < get_max_used_key_length(range_scan)) {
2845 24 destroy(tab->range_scan());
2846 24 tab->set_range_scan(range_scan);
2847 24 return true;
2848 }
2849
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
14 Opt_trace_object(trace, "access_type_unchanged")
2850 14 .add("ref_key_length", length)
2851
3/6
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
7 .add("range_key_length", get_max_used_key_length(range_scan));
2852 7 destroy(range_scan);
2853 }
2854
8/8
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 24 times.
✓ Branch 6 taken 13 times.
✓ Branch 7 taken 24 times.
109 } else
2855
1/2
✓ Branch 0 taken 75859 times.
✗ Branch 1 not taken.
75859 return length < get_max_used_key_length(tab->range_scan()); // 5)
2856 }
2857 }
2858 1947092 return false;
2859 }
2860
2861 /**
2862 An utility function - apply heuristics and optimize access methods to tables.
2863 Currently this function can change REF to RANGE and ALL to INDEX scan if
2864 latter is considered to be better (not cost-based) than the former.
2865 @note Side effect - this function could set 'Impossible WHERE' zero
2866 result.
2867 */
2868
2869 1815625 void JOIN::adjust_access_methods() {
2870
3/6
✓ Branch 0 taken 1815629 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1815635 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1815640 times.
✗ Branch 5 not taken.
1815625 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
2871
2/2
✓ Branch 0 taken 6295684 times.
✓ Branch 1 taken 1815654 times.
8111338 for (uint i = const_tables; i < tables; i++) {
2872 6295684 JOIN_TAB *const tab = best_ref[i];
2873 6295684 TABLE_LIST *const tl = tab->table_ref;
2874
2875
2/2
✓ Branch 0 taken 1774526 times.
✓ Branch 1 taken 4521171 times.
6295684 if (tab->type() == JT_ALL) {
2876 /*
2877 It's possible to speedup query by switching from full table scan to
2878 the scan of covering index, due to less data being read.
2879 Prerequisites for this are:
2880 1) Keyread (i.e index only scan) is allowed (table isn't updated/deleted
2881 from)
2882 2) Covering indexes are available
2883 3) This isn't a derived table/materialized view
2884 */
2885 1774526 if (!tab->table()->no_keyread && // 1
2886
6/6
✓ Branch 0 taken 1716052 times.
✓ Branch 1 taken 58483 times.
✓ Branch 2 taken 383949 times.
✓ Branch 3 taken 1332111 times.
✓ Branch 4 taken 383849 times.
✓ Branch 5 taken 1390691 times.
2158481 !tab->table()->covering_keys.is_clear_all() && // 2
2887
2/2
✓ Branch 0 taken 383850 times.
✓ Branch 1 taken 96 times.
383949 !tl->uses_materialization()) // 3
2888 {
2889 /*
2890 It has turned out that the change commented out below, while speeding
2891 things up for disk-bound loads, slows them down for cases when the data
2892 is in disk cache (see BUG#35850):
2893 // See bug #26447: "Using the clustered index for a table scan
2894 // is always faster than using a secondary index".
2895 if (table->s->primary_key != MAX_KEY &&
2896 table->file->primary_key_is_clustered())
2897 tab->index= table->s->primary_key;
2898 else
2899 tab->index=find_shortest_key(table, & table->covering_keys);
2900 */
2901
2/2
✓ Branch 0 taken 383797 times.
✓ Branch 1 taken 51 times.
383849 if (tab->position()->sj_strategy != SJ_OPT_LOOSE_SCAN)
2902 383796 tab->set_index(
2903 383797 find_shortest_key(tab->table(), &tab->table()->covering_keys));
2904 383849 tab->set_type(JT_INDEX_SCAN); // Read with index_first / index_next
2905 // From table scan to index scan, thus filter effect needs no recalc.
2906
6/6
✓ Branch 0 taken 1332206 times.
✓ Branch 1 taken 58486 times.
✓ Branch 2 taken 1190170 times.
✓ Branch 3 taken 142033 times.
✓ Branch 4 taken 1190168 times.
✓ Branch 5 taken 200521 times.
1390691 } else if (!tab->table()->no_keyread && !tl->uses_materialization()) {
2907
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1190173 times.
1190168 assert(tab->table()->covering_keys.is_clear_all());
2908
1/2
✓ Branch 0 taken 1190173 times.
✗ Branch 1 not taken.
1190173 if (tab->position()->sj_strategy != SJ_OPT_LOOSE_SCAN) {
2909
1/2
✓ Branch 0 taken 1190173 times.
✗ Branch 1 not taken.
1190173 Key_map clustering_keys;
2910
2/2
✓ Branch 0 taken 1507533 times.
✓ Branch 1 taken 1190170 times.
2697706 for (uint i2 = 0; i2 < tab->table()->s->keys; i2++) {
2911
3/4
✓ Branch 0 taken 614208 times.
✓ Branch 1 taken 893324 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1507532 times.
2121741 if (tab->keys().is_set(i2) &&
2912
2/4
✓ Branch 0 taken 614208 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 614208 times.
614208 tab->table()->file->index_flags(i2, 0, 0) & HA_CLUSTERED_INDEX)
2913 clustering_keys.set_bit(i2);
2914 }
2915
1/2
✓ Branch 0 taken 1190169 times.
✗ Branch 1 not taken.
1190170 uint index = find_shortest_key(tab->table(), &clustering_keys);
2916
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1190169 times.
1190169 if (index != MAX_KEY) {
2917 tab->set_type(JT_INDEX_SCAN);
2918 tab->set_index(index);
2919 }
2920 }
2921 }
2922
2/2
✓ Branch 0 taken 2022690 times.
✓ Branch 1 taken 2498486 times.
4521171 } else if (tab->type() == JT_REF) {
2923
2/2
✓ Branch 0 taken 1017 times.
✓ Branch 1 taken 2021657 times.
2022690 if (can_switch_from_ref_to_range(thd, tab, ORDER_NOT_RELEVANT, false)) {
2924 1017 tab->set_type(JT_RANGE);
2925
2926 1017 Opt_trace_context *const trace = &thd->opt_trace;
2927
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 Opt_trace_object wrapper(trace);
2928
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
2034 Opt_trace_object(trace, "access_type_changed")
2929
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 .add_utf8_table(tl)
2930 2034 .add_utf8("index",
2931
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 tab->table()->key_info[tab->position()->key->key].name)
2932
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 .add_alnum("old_type", "ref")
2933
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 .add_alnum("new_type", join_type_str[tab->type()])
2934
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 .add_alnum("cause", "uses_more_keyparts");
2935
2936 1017 tab->use_quick = QS_RANGE;
2937 1017 tab->position()->filter_effect = COND_FILTER_STALE;
2938 1017 } else {
2939 // Cleanup quick, REF/REF_OR_NULL/EQ_REF, will be clarified later
2940 2021657 ::destroy(tab->range_scan());
2941 2021657 tab->set_range_scan(nullptr);
2942 }
2943 }
2944 // Ensure AM consistency
2945
4/6
✓ Branch 0 taken 32149 times.
✓ Branch 1 taken 6263554 times.
✓ Branch 2 taken 32149 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32149 times.
✗ Branch 5 not taken.
6295711 assert(!(tab->range_scan() &&
2946 (tab->type() == JT_REF || tab->type() == JT_ALL)));
2947
5/6
✓ Branch 0 taken 6264690 times.
✓ Branch 1 taken 31026 times.
✓ Branch 2 taken 6263570 times.
✓ Branch 3 taken 1122 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32149 times.
6295703 assert((tab->type() != JT_RANGE && tab->type() != JT_INDEX_MERGE) ||
2948 tab->range_scan());
2949 6295719 if (!tab->const_keys.is_clear_all() &&
2950
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 533987 times.
533997 tab->table()->reginfo.impossible_range &&
2951
5/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 4 times.
20 ((i == const_tables && tab->type() == JT_REF) ||
2952
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
22 ((tab->type() == JT_ALL || tab->type() == JT_RANGE ||
2953
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
12 tab->type() == JT_INDEX_MERGE || tab->type() == JT_INDEX_SCAN) &&
2954
5/6
✓ Branch 0 taken 533997 times.
✓ Branch 1 taken 5761725 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 6295698 times.
6829723 tab->use_quick != QS_RANGE)) &&
2955
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
24 !tab->table_ref->is_inner_table_of_outer_join())
2956 4 zero_result_cause = "Impossible WHERE noticed after reading const tables";
2957 }
2958 1815654 }
2959
2960 3824086 static JOIN_TAB *alloc_jtab_array(THD *thd, uint table_count) {
2961
5/8
✓ Branch 0 taken 3824095 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3824114 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6499285 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6499280 times.
✓ Branch 7 taken 3824119 times.
10323366 JOIN_TAB *t = new (thd->mem_root) JOIN_TAB[table_count];
2962
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3824119 times.
3824119 if (!t) return nullptr; /* purecov: inspected */
2963
2964
5/8
✓ Branch 0 taken 3824121 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3824121 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6499241 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6499258 times.
✓ Branch 7 taken 3824104 times.
10323360 QEP_shared *qs = new (thd->mem_root) QEP_shared[table_count];
2965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3824104 times.
3824104 if (!qs) return nullptr; /* purecov: inspected */
2966
2967
2/2
✓ Branch 0 taken 6499275 times.
✓ Branch 1 taken 3824101 times.
10323375 for (uint i = 0; i < table_count; ++i) t[i].set_qs(qs++);
2968
2969 3824101 return t;
2970 }
2971
2972 /**
2973 Set up JOIN_TAB structs according to the picked join order in best_positions.
2974 This allocates execution structures so may be called only after we have the
2975 very final plan. It must be called after
2976 Optimize_table_order::fix_semijoin_strategies().
2977
2978 @return False if success, True if error
2979
2980 @details
2981 - create join->join_tab array and copy from existing JOIN_TABs in join order
2982 - create helper structs for materialized semi-join handling
2983 - finalize semi-join strategy choices
2984 - Number of intermediate tables "tmp_tables" is calculated.
2985 - "tables" and "primary_tables" are recalculated.
2986 - for full and index scans info of estimated # of records is updated.
2987 - in a helper function:
2988 - all heuristics are applied and the final access method type is picked
2989 for each join_tab (only test_if_skip_sortorder() could override it)
2990 - AM consistency is ensured (e.g only range and index merge are allowed
2991 to have quick select set).
2992 - if "Impossible WHERE" is detected - appropriate zero_result_cause is
2993 set.
2994
2995 Notice that intermediate tables will not have a POSITION reference; and they
2996 will not have a TABLE reference before the final stages of code generation.
2997
2998 @todo the block which sets tab->type should move to adjust_access_methods
2999 for unification.
3000 */
3001
3002 1911974 bool JOIN::get_best_combination() {
3003
1/2
✓ Branch 0 taken 1911999 times.
✗ Branch 1 not taken.
1911974 DBUG_TRACE;
3004
3005 // At this point "tables" and "primary"tables" represent the same:
3006
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1911999 times.
1911999 assert(tables == primary_tables);
3007
3008 /*
3009 Allocate additional space for tmp tables.
3010 Number of plan nodes:
3011 # of regular input tables (including semi-joined ones) +
3012 # of semi-join nests for materialization +
3013 1? + // For GROUP BY (or implicit grouping when we have windowing)
3014 1? + // For DISTINCT
3015 1? + // For aggregation functions aggregated in outer query
3016 // when used with distinct
3017 1? + // For ORDER BY
3018 1? // buffer result
3019
3020 Up to 2 tmp tables + N window output tmp are allocated (NOTE: windows also
3021 have frame buffer tmp tables, but those are not relevant here).
3022 */
3023 uint num_tmp_tables =
3024
4/4
✓ Branch 0 taken 420548 times.
✓ Branch 1 taken 1480994 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 420530 times.
3813541 (!group_list.empty() || (implicit_grouping && m_windows.elements > 0)
3025
2/2
✓ Branch 0 taken 1901542 times.
✓ Branch 1 taken 10443 times.
3813527 ? 1
3026 1911985 : 0) +
3027
4/4
✓ Branch 0 taken 4012 times.
✓ Branch 1 taken 1907973 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 3975 times.
1911985 (select_distinct ? (tmp_table_param.outer_sum_func_count ? 2 : 1) : 0) +
3028
2/2
✓ Branch 0 taken 1272970 times.
✓ Branch 1 taken 639020 times.
1911985 (order.empty() ? 0 : 1) +
3029 1911990 (query_block->active_options() &
3030 (SELECT_BIG_RESULT | OPTION_BUFFER_RESULT)
3031
2/2
✓ Branch 0 taken 7203 times.
✓ Branch 1 taken 1904788 times.
1911991 ? 1
3032 1911991 : 0) +
3033 1911991 m_windows.elements + 1; /* the presence of windows may increase need for
3034 grouping tmp tables, cf. de-optimization
3035 in make_tmp_tables_info
3036 */
3037
2/2
✓ Branch 0 taken 4669 times.
✓ Branch 1 taken 1907322 times.
1911991 if (num_tmp_tables > (2 + m_windows.elements))
3038 4669 num_tmp_tables = 2 + m_windows.elements;
3039
3040 /*
3041 Rearrange queries with materialized semi-join nests so that the semi-join
3042 nest is replaced with a reference to a materialized temporary table and all
3043 materialized subquery tables are placed after the intermediate tables.
3044 After the following loop, "inner_target" is the position of the first
3045 subquery table (if any). "outer_target" is the position of first outer
3046 table, and will later be used to track the position of any materialized
3047 temporary tables.
3048 */
3049
1/2
✓ Branch 0 taken 1911997 times.
✗ Branch 1 not taken.
1911991 const bool has_semijoin = !query_block->sj_nests.empty();
3050 1911997 uint outer_target = 0;
3051 1911997 uint inner_target = primary_tables + num_tmp_tables;
3052 1911997 uint sjm_nests = 0;
3053
3054
2/2
✓ Branch 0 taken 2721 times.
✓ Branch 1 taken 1909276 times.
1911997 if (has_semijoin) {
3055
2/2
✓ Branch 0 taken 14354 times.
✓ Branch 1 taken 2721 times.
17075 for (uint tableno = 0; tableno < primary_tables;) {
3056
2/2
✓ Branch 0 taken 934 times.
✓ Branch 1 taken 13420 times.
14354 if (sj_is_materialize_strategy(best_positions[tableno].sj_strategy)) {
3057 934 sjm_nests++;
3058 934 inner_target -= (best_positions[tableno].n_sj_tables - 1);
3059 934 tableno += best_positions[tableno].n_sj_tables;
3060 } else
3061 13420 tableno++;
3062 }
3063 }
3064
3065 1911997 JOIN_TAB *tmp_join_tabs = nullptr;
3066
2/2
✓ Branch 0 taken 1911985 times.
✓ Branch 1 taken 12 times.
1911997 if (sjm_nests + num_tmp_tables) {
3067 // join_tab array only has "primary_tables" tables. We need those more:
3068
2/4
✓ Branch 0 taken 1911996 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1911996 times.
1911985 if (!(tmp_join_tabs = alloc_jtab_array(thd, sjm_nests + num_tmp_tables)))
3069 return true; /* purecov: inspected */
3070 }
3071
3072 // To check that we fill the array correctly: fill it with zeros first
3073 1912008 memset(best_ref, 0,
3074 1912008 sizeof(JOIN_TAB *) * (primary_tables + sjm_nests + num_tmp_tables));
3075
3076 1912008 int sjm_index = tables; // Number assigned to materialized temporary table
3077 1912008 int remaining_sjm_inner = 0;
3078 1912008 bool err = false;
3079
2/2
✓ Branch 0 taken 3928386 times.
✓ Branch 1 taken 1912021 times.
5840407 for (uint tableno = 0; tableno < tables; tableno++) {
3080 3928386 POSITION *const pos = best_positions + tableno;
3081
6/6
✓ Branch 0 taken 15794 times.
✓ Branch 1 taken 3912592 times.
✓ Branch 2 taken 934 times.
✓ Branch 3 taken 14860 times.
✓ Branch 4 taken 934 times.
✓ Branch 5 taken 3927452 times.
3928386 if (has_semijoin && sj_is_materialize_strategy(pos->sj_strategy)) {
3082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 934 times.
934 assert(outer_target < inner_target);
3083
3084 934 TABLE_LIST *const sj_nest = pos->table->emb_sj_nest;
3085
3086 // Handle this many inner tables of materialized semi-join
3087 934 remaining_sjm_inner = pos->n_sj_tables;
3088
3089 /*
3090 If we fail in some allocation below, we cannot bail out immediately;
3091 that would put us in a difficult situation to clean up; imagine we
3092 have planned this layout:
3093 outer1 - sj_mat_tmp1 - outer2 - sj_mat_tmp2 - outer3
3094 We have successfully filled a JOIN_TAB for sj_mat_tmp1, and are
3095 failing to fill a JOIN_TAB for sj_mat_tmp2 (OOM). So we want to quit
3096 this function, which will lead to cleanup functions.
3097 But sj_mat_tmp1 is in this->best_ref only, outer3 is in this->join_tab
3098 only: what is the array to traverse for cleaning up? What is the
3099 number of tables to loop over?
3100 So: if we fail in the present loop, we record the error but continue
3101 filling best_ref; when it's fully filled, bail out, because then
3102 best_ref can be used as reliable array for cleaning up.
3103 */
3104 934 JOIN_TAB *const tab = tmp_join_tabs++;
3105 934 best_ref[outer_target] = tab;
3106 934 tab->set_join(this);
3107 934 tab->set_idx(outer_target);
3108
3109 /*
3110 Up to this point there cannot be a failure. JOIN_TAB has been filled
3111 enough to be clean-able.
3112 */
3113
3114 934 Semijoin_mat_exec *const sjm_exec = new (thd->mem_root) Semijoin_mat_exec(
3115 934 sj_nest, (pos->sj_strategy == SJ_OPT_MATERIALIZE_SCAN),
3116
2/4
✓ Branch 0 taken 934 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 934 times.
✗ Branch 3 not taken.
934 remaining_sjm_inner, outer_target, inner_target);
3117
3118 934 tab->set_sj_mat_exec(sjm_exec);
3119
3120
3/6
✓ Branch 0 taken 934 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 934 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 934 times.
1868 if (!sjm_exec || setup_semijoin_materialized_table(
3121
1/2
✓ Branch 0 taken 934 times.
✗ Branch 1 not taken.
934 tab, sjm_index, pos, best_positions + sjm_index))
3122 err = true; /* purecov: inspected */
3123
3124 934 outer_target++;
3125 934 sjm_index++;
3126 }
3127 /*
3128 Locate join_tab target for the table we are considering.
3129 (remaining_sjm_inner becomes negative for non-SJM tables, this can be
3130 safely ignored).
3131 */
3132 const uint target =
3133
2/2
✓ Branch 0 taken 2374 times.
✓ Branch 1 taken 3926012 times.
3928386 (remaining_sjm_inner--) > 0 ? inner_target++ : outer_target++;
3134 3928386 JOIN_TAB *const tab = pos->table;
3135
3136 3928386 best_ref[target] = tab;
3137 3928386 tab->set_idx(target);
3138 3928383 tab->set_position(pos);
3139 3928395 TABLE *const table = tab->table();
3140
6/6
✓ Branch 0 taken 3841996 times.
✓ Branch 1 taken 86409 times.
✓ Branch 2 taken 3827436 times.
✓ Branch 3 taken 14560 times.
✓ Branch 4 taken 3827435 times.
✓ Branch 5 taken 100970 times.
3928401 if (tab->type() != JT_CONST && tab->type() != JT_SYSTEM) {
3141
5/6
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 3827372 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 55 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3827435 times.
3827443 if (pos->sj_strategy == SJ_OPT_LOOSE_SCAN && tab->range_scan() &&
3142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 used_index(tab->range_scan()) != pos->loosescan_key) {
3143 /*
3144 We must use the duplicate-eliminating index, so this QUICK is not
3145 an option.
3146 */
3147 ::destroy(tab->range_scan());
3148 tab->set_range_scan(nullptr);
3149 }
3150
2/2
✓ Branch 0 taken 1804853 times.
✓ Branch 1 taken 2022577 times.
3827430 if (!pos->key) {
3151
2/2
✓ Branch 0 taken 31132 times.
✓ Branch 1 taken 1773719 times.
1804853 if (tab->range_scan())
3152
1/2
✓ Branch 0 taken 31132 times.
✗ Branch 1 not taken.
31132 tab->set_type(calc_join_type(tab->range_scan()));
3153 else
3154 1773719 tab->set_type(JT_ALL);
3155 } else
3156 // REF or RANGE, clarify later when prefix tables are set for JOIN_TABs
3157 2022577 tab->set_type(JT_REF);
3158 }
3159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3928404 times.
3928395 assert(tab->type() != JT_UNKNOWN);
3160
3161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3928404 times.
3928404 assert(table->reginfo.join_tab == tab);
3162
2/2
✓ Branch 0 taken 3526468 times.
✓ Branch 1 taken 401930 times.
3928404 if (!tab->join_cond())
3163 3526468 table->reginfo.not_exists_optimize = false; // Only with LEFT JOIN
3164 3928398 map2table[tab->table_ref->tableno()] = tab;
3165 }
3166
3167 // Count the materialized semi-join tables as regular input tables
3168 1912021 tables += sjm_nests + num_tmp_tables;
3169 // Set the number of non-materialized tables:
3170 1912021 primary_tables = outer_target;
3171
3172 /*
3173 Between the last outer table or sj-mat tmp table, and the first sj-mat
3174 inner table, there may be 2 slots for sort/group/etc tmp tables:
3175 */
3176
2/2
✓ Branch 0 taken 2569761 times.
✓ Branch 1 taken 1912019 times.
4481780 for (uint i = 0; i < num_tmp_tables; ++i) {
3177 2569761 const uint idx = outer_target + i;
3178 2569761 tmp_join_tabs->set_join(this);
3179 2569760 tmp_join_tabs->set_idx(idx);
3180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2569759 times.
2569759 assert(best_ref[idx] == nullptr); // verify that not overwriting
3181 2569759 best_ref[idx] = tmp_join_tabs++;
3182 /*
3183 note that set_table() cannot be called yet. We may not even use this
3184 JOIN_TAB in the end, it's dummy at the moment. Which can be tested with
3185 "position()!=NULL".
3186 */
3187 }
3188
3189 // make array unreachable: should walk JOIN_TABs by best_ref now
3190 1912019 join_tab = nullptr;
3191
3192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1912019 times.
1912019 if (err) return true; /* purecov: inspected */
3193
3194
2/2
✓ Branch 0 taken 2721 times.
✓ Branch 1 taken 1909298 times.
1912019 if (has_semijoin) {
3195
1/2
✓ Branch 0 taken 2721 times.
✗ Branch 1 not taken.
2721 set_semijoin_info();
3196
3197 // Update equalities and keyuses after having added SJ materialization
3198
2/4
✓ Branch 0 taken 2721 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2721 times.
2721 if (update_equalities_for_sjm()) return true;
3199 }
3200
2/2
✓ Branch 0 taken 1815642 times.
✓ Branch 1 taken 96355 times.
1912019 if (!plan_is_const()) {
3201 // Assign map of "available" tables to all tables belonging to query block
3202
1/2
✓ Branch 0 taken 1815642 times.
✗ Branch 1 not taken.
1815642 set_prefix_tables();
3203
1/2
✓ Branch 0 taken 1815641 times.
✗ Branch 1 not taken.
1815642 adjust_access_methods();
3204 }
3205 // Calculate outer join info
3206
3/4
✓ Branch 0 taken 150680 times.
✓ Branch 1 taken 1761316 times.
✓ Branch 2 taken 150680 times.
✗ Branch 3 not taken.
1911996 if (query_block->outer_join) make_outerjoin_info();
3207
3208 // sjm is no longer needed, trash it. To reuse it, reset its members!
3209
7/12
✓ Branch 0 taken 1911999 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1911999 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2783 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2783 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1914782 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2783 times.
✓ Branch 11 taken 1911999 times.
1914779 for (TABLE_LIST *sj_nest : query_block->sj_nests) {
3210 2783 TRASH(static_cast<void *>(&sj_nest->nested_join->sjm),
3211 sizeof(sj_nest->nested_join->sjm));
3212 }
3213
3214 1911999 return false;
3215 1911999 }
3216
3217 /**
3218 Finds the dependencies of the remaining lateral derived tables.
3219
3220 @param plan_tables map of all tables that the planner is processing
3221 (tables already in plan and tables to be added to plan).
3222 @param idx index of the table which the planner is currently
3223 considering.
3224 @return A map of the dependencies of the remaining
3225 lateral derived tables (from best_ref[idx] and on).
3226 */
3227 7749 table_map JOIN::calculate_deps_of_remaining_lateral_derived_tables(
3228 table_map plan_tables, uint idx) const {
3229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7749 times.
7749 assert(has_lateral);
3230 7749 table_map deps = 0;
3231 7749 auto last = best_ref + tables;
3232
2/2
✓ Branch 0 taken 27589 times.
✓ Branch 1 taken 7749 times.
35338 for (auto **pos = best_ref + idx; pos < last; pos++) {
3233
6/6
✓ Branch 0 taken 26907 times.
✓ Branch 1 taken 682 times.
✓ Branch 2 taken 26898 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 26898 times.
✓ Branch 5 taken 691 times.
27589 if ((*pos)->table_ref && ((*pos)->table_ref->map() & plan_tables)) {
3234 26898 deps |= get_lateral_deps(**pos);
3235 }
3236 }
3237 7749 return deps;
3238 }
3239
3240 /*
3241 Revise usage of join buffer for the specified table and the whole nest
3242
3243 SYNOPSIS
3244 revise_cache_usage()
3245 tab join table for which join buffer usage is to be revised
3246
3247 DESCRIPTION
3248 The function revise the decision to use a join buffer for the table 'tab'.
3249 If this table happened to be among the inner tables of a nested outer join/
3250 semi-join the functions denies usage of join buffers for all of them
3251
3252 RETURN
3253 none
3254 */
3255
3256 1892237 static void revise_cache_usage(JOIN_TAB *join_tab) {
3257 1892237 plan_idx first_inner = join_tab->first_inner();
3258 1892245 JOIN *const join = join_tab->join();
3259
2/2
✓ Branch 0 taken 398163 times.
✓ Branch 1 taken 1494084 times.
1892247 if (first_inner != NO_PLAN_IDX) {
3260 398163 plan_idx end_tab = join_tab->idx();
3261
2/2
✓ Branch 0 taken 398512 times.
✓ Branch 1 taken 398163 times.
796675 for (first_inner = join_tab->first_inner(); first_inner != NO_PLAN_IDX;
3262 398512 first_inner = join->best_ref[first_inner]->first_upper()) {
3263
2/2
✓ Branch 0 taken 2844 times.
✓ Branch 1 taken 398512 times.
401356 for (plan_idx i = end_tab - 1; i >= first_inner; --i)
3264 2844 join->best_ref[i]->set_use_join_cache(JOIN_CACHE::ALG_NONE);
3265 398512 end_tab = first_inner;
3266 }
3267
2/2
✓ Branch 0 taken 437 times.
✓ Branch 1 taken 1493650 times.
1494084 } else if (join_tab->get_sj_strategy() == SJ_OPT_FIRST_MATCH) {
3268 437 plan_idx first_sj_inner = join_tab->first_sj_inner();
3269
2/2
✓ Branch 0 taken 1744 times.
✓ Branch 1 taken 437 times.
2181 for (plan_idx i = join_tab->idx() - 1; i >= first_sj_inner; --i) {
3270 1744 JOIN_TAB *tab = join->best_ref[i];
3271
1/2
✓ Branch 0 taken 1744 times.
✗ Branch 1 not taken.
1744 if (tab->first_sj_inner() == first_sj_inner)
3272 1744 tab->set_use_join_cache(JOIN_CACHE::ALG_NONE);
3273 }
3274 } else
3275 1493650 join_tab->set_use_join_cache(JOIN_CACHE::ALG_NONE);
3276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1892241 times.
1892241 assert(join->qep_tab == nullptr);
3277 1892241 }
3278
3279 /**
3280 Set up join buffering for a specified table, if possible.
3281
3282 @param tab joined table to check join buffer usage for
3283 @param join join for which the check is performed
3284 @param no_jbuf_after don't use join buffering after table with this number
3285
3286 @return false if successful, true if error.
3287 Currently, allocation errors for join cache objects are ignored,
3288 and regular execution is chosen silently.
3289
3290 @details
3291 The function finds out whether the table 'tab' can be joined using a join
3292 buffer. This check is performed after the best execution plan for 'join'
3293 has been chosen. If the function decides that a join buffer can be employed
3294 then it selects the most appropriate join cache type, which later will
3295 be instantiated by init_join_cache().
3296 If it has already been decided to not use join buffering for this table,
3297 no action is taken.
3298
3299 Often it is already decided that join buffering will be used earlier in
3300 the optimization process, and this will also ensure that the most correct
3301 cost for the operation is calculated, and hence the probability of
3302 choosing an optimal join plan is higher. However, some join buffering
3303 decisions cannot currently be taken before this stage, hence we need this
3304 function to decide the most accurate join buffering strategy.
3305
3306 @todo Long-term it is the goal that join buffering strategy is decided
3307 when the plan is selected.
3308
3309 The result of the check and the type of the join buffer to be used
3310 depend on:
3311 - the access method to access rows of the joined table
3312 - whether the join table is an inner table of an outer join or semi-join
3313 - the optimizer_switch settings for join buffering
3314 - the join 'options'.
3315 In any case join buffer is not used if the number of the joined table is
3316 greater than 'no_jbuf_after'.
3317
3318 If block_nested_loop is turned on, and if all other criteria for using
3319 join buffering is fulfilled (see below), then join buffer is used
3320 for any join operation (inner join, outer join, semi-join) with 'JT_ALL'
3321 access method. In that case, a JOIN_CACHE_BNL type is always employed.
3322
3323 If an index is used to access rows of the joined table and
3324 batched_key_access is on, then a JOIN_CACHE_BKA type is employed.
3325
3326 If the function decides that a join buffer can be used to join the table
3327 'tab' then it sets @c tab->use_join_cache to reflect the chosen algorithm.
3328
3329 @note
3330 For a nested outer join/semi-join, currently, we either use join buffers for
3331 all inner tables or for none of them.
3332
3333 Join buffering is enabled for a few more cases for secondary engine.
3334 Currently if blocked nested loop(BNL) is employed for join buffering,
3335 it is replaced by hash joins in the executor. So the reasons for disabling
3336 join buffering because of the way BNL works are no more valid. This gives
3337 us an oppotunity to enable join buffering for more cases. However,
3338 we enable it only for secondary engine (in particular for semijoins),
3339 because of the following reasons:
3340 Secondary engine does not care about the cost based decisions
3341 involved in arriving at the best possible semijoin strategy;
3342 because it can only interpret a plan using "FirstMatch" strategy
3343 and can only do table scans. So the choices are very limited.
3344 However, it's not the case for mysql. There are serveral semijoin
3345 stratagies that could be picked. And these are picked based
3346 on the assumption that a nested-loop join(NLJ) would be used because
3347 optimizer currently generates plans only for NLJs and not
3348 hash joins. So, when executor replaces with hash joins, the number
3349 of rows that would be looked into for a particular semijoin strategy
3350 will differ from what the optimizer presumed while picking that
3351 strategy.
3352 For mysql server, we could enable join buffering for more cases, when
3353 a cost model for using hash joins is developed and optimizer could
3354 generate plans for hash joins.
3355
3356 @todo
3357 Support BKA inside SJ-Materialization nests. When doing this, we'll need
3358 to only store sj-inner tables in the join buffer.
3359 @verbatim
3360 JOIN_TAB *first_tab= join->join_tab+join->const_tables;
3361 uint n_tables= i-join->const_tables;
3362 / *
3363 We normally put all preceding tables into the join buffer, except
3364 for the constant tables.
3365 If we're inside a semi-join materialization nest, e.g.
3366
3367 outer_tbl1 outer_tbl2 ( inner_tbl1, inner_tbl2 ) ...
3368 ^-- we're here
3369
3370 then we need to put into the join buffer only the tables from
3371 within the nest.
3372 * /
3373 if (i >= first_sjm_table && i < last_sjm_table)
3374 {
3375 n_tables= i - first_sjm_table; // will be >0 if we got here
3376 first_tab= join->join_tab + first_sjm_table;
3377 }
3378 @endverbatim
3379 */
3380
3381 3826290 static bool setup_join_buffering(JOIN_TAB *tab, JOIN *join,
3382 uint no_jbuf_after) {
3383
3/6
✓ Branch 0 taken 3826294 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3826300 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3826306 times.
✗ Branch 5 not taken.
3826290 ASSERT_BEST_REF_IN_JOIN_ORDER(join);
3384 3826302 Cost_estimate cost;
3385 ha_rows rows;
3386 3826298 uint bufsz = 4096;
3387 3826298 uint join_cache_flags = 0;
3388
1/2
✓ Branch 0 taken 3826304 times.
✗ Branch 1 not taken.
3826298 const bool bnl_on = hint_table_state(join->thd, tab->table_ref, BNL_HINT_ENUM,
3389 OPTIMIZER_SWITCH_BNL);
3390
1/2
✓ Branch 0 taken 3826311 times.
✗ Branch 1 not taken.
3826304 const bool bka_on = hint_table_state(join->thd, tab->table_ref, BKA_HINT_ENUM,
3391 OPTIMIZER_SWITCH_BKA);
3392
3393 3826311 const uint tableno = tab->idx();
3394
1/2
✓ Branch 0 taken 3826313 times.
✗ Branch 1 not taken.
3826306 const uint tab_sj_strategy = tab->get_sj_strategy();
3395
3396 /*
3397 If all key_parts are null_rejecting, the MultiRangeRowIterator will
3398 eliminate all NULL values in the key set, such that
3399 HA_MRR_NO_NULL_ENDPOINTS can be promised.
3400 */
3401 3826313 const key_part_map keypart_map = make_prev_keypart_map(tab->ref().key_parts);
3402
2/2
✓ Branch 0 taken 2279581 times.
✓ Branch 1 taken 1546734 times.
3826314 if (tab->ref().null_rejecting == keypart_map) {
3403 2279581 join_cache_flags |= HA_MRR_NO_NULL_ENDPOINTS;
3404 }
3405
3406 // Set preliminary join cache setting based on decision from greedy search
3407
2/2
✓ Branch 0 taken 3810966 times.
✓ Branch 1 taken 15349 times.
3826315 if (!join->select_count)
3408
2/2
✓ Branch 0 taken 171895 times.
✓ Branch 1 taken 3639073 times.
3810966 tab->set_use_join_cache(tab->position()->use_join_buffer
3409 ? JOIN_CACHE::ALG_BNL
3410 : JOIN_CACHE::ALG_NONE);
3411
3412
2/2
✓ Branch 0 taken 1813739 times.
✓ Branch 1 taken 2012576 times.
3826315 if (tableno == join->const_tables) {
3413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1813734 times.
1813739 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3414 1813734 return false;
3415 }
3416
3417
4/4
✓ Branch 0 taken 2248 times.
✓ Branch 1 taken 2010328 times.
✓ Branch 2 taken 541 times.
✓ Branch 3 taken 1707 times.
2012576 if (!(bnl_on || bka_on)) goto no_join_cache;
3418
3419 /*
3420 psergey-todo: why the below when execution code seems to handle the
3421 "range checked for each record" case?
3422 */
3423
2/2
✓ Branch 0 taken 356 times.
✓ Branch 1 taken 2011679 times.
2012035 if (tab->use_quick == QS_DYNAMIC_RANGE) goto no_join_cache;
3424
3425 /* No join buffering if prevented by no_jbuf_after */
3426
2/2
✓ Branch 0 taken 64333 times.
✓ Branch 1 taken 1947346 times.
2011679 if (tableno > no_jbuf_after) goto no_join_cache;
3427
3428 /*
3429 An inner table of an outer join nest must not use join buffering if
3430 the first inner table of that outer join nest does not use join buffering.
3431 This condition is not handled by earlier optimizer stages.
3432 */
3433
8/8
✓ Branch 0 taken 404419 times.
✓ Branch 1 taken 1542926 times.
✓ Branch 2 taken 1301 times.
✓ Branch 3 taken 403118 times.
✓ Branch 4 taken 639 times.
✓ Branch 5 taken 651 times.
✓ Branch 6 taken 639 times.
✓ Branch 7 taken 1946695 times.
1948636 if (tab->first_inner() != NO_PLAN_IDX && tab->first_inner() != tab->idx() &&
3434 1301 !join->best_ref[tab->first_inner()]->use_join_cache())
3435 639 goto no_join_cache;
3436 /*
3437 The first inner table of an outer join nest must not use join buffering
3438 if the tables in the embedding outer join nest do not use join buffering.
3439 This condition is not handled by earlier optimizer stages.
3440 */
3441
6/6
✓ Branch 0 taken 530 times.
✓ Branch 1 taken 1946171 times.
✓ Branch 2 taken 227 times.
✓ Branch 3 taken 300 times.
✓ Branch 4 taken 227 times.
✓ Branch 5 taken 1946471 times.
1947222 if (tab->first_upper() != NO_PLAN_IDX &&
3442 530 !join->best_ref[tab->first_upper()]->use_join_cache())
3443 227 goto no_join_cache;
3444
3445
6/6
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 1946336 times.
✓ Branch 2 taken 128 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 128 times.
✓ Branch 5 taken 1946341 times.
1946471 if (tab->table()->pos_in_table_list->is_table_function() && tab->dependent)
3446 128 goto no_join_cache;
3447
3448
5/5
✓ Branch 0 taken 323 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 2353 times.
✓ Branch 3 taken 1943646 times.
✓ Branch 4 taken 6 times.
1946341 switch (tab_sj_strategy) {
3449 323 case SJ_OPT_FIRST_MATCH:
3450 /*
3451 Use join cache with FirstMatch semi-join strategy only when semi-join
3452 contains only one table.
3453 As mentioned earlier (in comments), we lift this restriction for
3454 secondary engine.
3455 */
3456
3/6
✓ Branch 0 taken 323 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 323 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 323 times.
✗ Branch 5 not taken.
646 if (!(current_thd->lex->m_sql_cmd != nullptr &&
3457
2/4
✓ Branch 0 taken 323 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 323 times.
✗ Branch 3 not taken.
323 current_thd->lex->m_sql_cmd->using_secondary_storage_engine())) {
3458
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 199 times.
323 if (!tab->is_single_inner_of_semi_join()) {
3459
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 124 times.
124 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3460 124 goto no_join_cache;
3461 }
3462 }
3463 199 break;
3464
3465 13 case SJ_OPT_LOOSE_SCAN:
3466 /* No join buffering if this semijoin nest is handled by loosescan */
3467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3468 13 goto no_join_cache;
3469
3470 2353 case SJ_OPT_MATERIALIZE_LOOKUP:
3471 case SJ_OPT_MATERIALIZE_SCAN:
3472 /*
3473 The Materialize strategies reuse the join_tab belonging to the
3474 first table that was materialized. Neither table can use join buffering:
3475 - The first table in a join never uses join buffering.
3476 - The join_tab used for looking up a row in the materialized table, or
3477 scanning the rows of a materialized table, cannot use join buffering.
3478 We allow join buffering for the remaining tables of the materialized
3479 semi-join nest.
3480 */
3481
2/2
✓ Branch 0 taken 917 times.
✓ Branch 1 taken 1436 times.
2353 if (tab->first_sj_inner() == tab->idx()) {
3482
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 917 times.
917 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3483 917 goto no_join_cache;
3484 }
3485 1436 break;
3486
3487 1943646 case SJ_OPT_DUPS_WEEDOUT:
3488 // This strategy allows the same join buffering as a regular join would.
3489 case SJ_OPT_NONE:
3490 1943646 break;
3491 }
3492
3493 /*
3494 The following code prevents use of join buffering when there is an
3495 outer join operation and first match semi-join strategy is used, because:
3496
3497 Outer join needs a "match flag" to track that a row should be
3498 NULL-complemented, such flag being attached to first inner table's cache
3499 (tracks whether the cached row from outer table got a match, in which case
3500 no NULL-complemented row is needed).
3501
3502 FirstMatch also needs a "match flag", such flag is attached to sj inner
3503 table's cache (tracks whether the cached row from outer table already got
3504 a first match in the sj-inner table, in which case we don't need to join
3505 this cached row again)
3506 - but a row in a cache has only one "match flag"
3507 - so if "sj inner table"=="first inner", there is a problem.
3508
3509 As mentioned earlier(in comments), we lift this restriction for
3510 secondary engine.
3511 */
3512
5/6
✓ Branch 0 taken 1945282 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1932109 times.
✓ Branch 3 taken 13173 times.
✓ Branch 4 taken 1945181 times.
✓ Branch 5 taken 109 times.
3877404 if (!(current_thd->lex->m_sql_cmd != nullptr &&
3513
3/4
✓ Branch 0 taken 1932113 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1932008 times.
✓ Branch 3 taken 109 times.
1932109 current_thd->lex->m_sql_cmd->using_secondary_storage_engine())) {
3514
4/6
✓ Branch 0 taken 199 times.
✓ Branch 1 taken 1944982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 199 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1945181 times.
1945380 if (tab_sj_strategy == SJ_OPT_FIRST_MATCH &&
3515 199 tab->is_inner_table_of_outer_join())
3516 goto no_join_cache;
3517 }
3518
3519 3890587 if (join->deps_of_remaining_lateral_derived_tables &
3520
2/2
✓ Branch 0 taken 634 times.
✓ Branch 1 taken 1944663 times.
1945290 (tab->prefix_tables() & ~tab->added_tables())) {
3521 /*
3522 Even though the planner said "no jbuf please", the switch below may
3523 force it.
3524 If first-dependency-of-lateral-table < table-we-plan-for <=
3525 lateral-table, disable join buffering.
3526 Reason for this rule:
3527 consider a plan t1-t2-dt where dt is LATERAL and depends only on t1, and
3528 imagine t2 could do join buffering: then we buffer many rows of t1, then
3529 read one row of t2, fetch row#1 of t1 from cache, then materialize "dt"
3530 (as it depends on t1) and send row to client; then fetch row#2 of t1
3531 from cache, rematerialize "dt": it's very inefficient. So we forbid join
3532 buffering on t2; this way, the signal "row of t1 changed" is emitted at
3533 the level of t1's operator, i.e. much less often, as one row of t1 may
3534 serve N rows of t2 before changing.
3535 On the other hand, t1 can do join buffering.
3536 A nice side-effect is to disable join buffering for "dt" itself. If
3537 "dt" would do join buffering: "dt" buffers many rows from t1/t2, then in a
3538 second phase we read one row from "dt" and join it with the many rows
3539 from t1/t2; but we cannot read a row from "dt" without first choosing a
3540 row of t1/t2 as "dt" depends on t1.
3541 See similar code in best_access_path().
3542 */
3543 634 goto no_join_cache;
3544 }
3545
3546
3/3
✓ Branch 0 taken 120849 times.
✓ Branch 1 taken 1823784 times.
✓ Branch 2 taken 32 times.
1944663 switch (tab->type()) {
3547 120849 case JT_ALL:
3548 case JT_INDEX_SCAN:
3549 case JT_RANGE:
3550 case JT_INDEX_MERGE:
3551
2/2
✓ Branch 0 taken 748 times.
✓ Branch 1 taken 120101 times.
120849 if (!bnl_on) {
3552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 748 times.
748 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3553 748 goto no_join_cache;
3554 }
3555
3556
2/2
✓ Branch 0 taken 120014 times.
✓ Branch 1 taken 87 times.
120101 if (!join->select_count) tab->set_use_join_cache(JOIN_CACHE::ALG_BNL);
3557 120101 return false;
3558 1823784 case JT_SYSTEM:
3559 case JT_CONST:
3560 case JT_REF:
3561 case JT_EQ_REF:
3562
2/2
✓ Branch 0 taken 1822475 times.
✓ Branch 1 taken 1309 times.
1823784 if (!bka_on) {
3563
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1822469 times.
1822475 assert(tab->use_join_cache() == JOIN_CACHE::ALG_NONE);
3564 1822469 goto no_join_cache;
3565 }
3566
3567 /*
3568 Disable BKA for materializable derived tables/views as they aren't
3569 instantiated yet.
3570 */
3571
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1304 times.
1309 if (tab->table_ref->uses_materialization()) goto no_join_cache;
3572
3573 /*
3574 Can't use BKA for subquery if dealing with a subquery that can
3575 turn a ref access into a "full scan on NULL key" table scan.
3576
3577 @see Item_in_optimizer::val_int()
3578 @see subselect_iterator_engine::exec()
3579 @see TABLE_REF::cond_guards
3580 @see push_index_cond()
3581
3582 @todo: This choice to not use BKA should be done before making
3583 cost estimates, e.g. in set_join_buffer_properties(). That
3584 happens before cond guards are set up, so instead of doing the
3585 check below, BKA should be disabled if
3586 - We are in an IN subquery, and
3587 - The IN predicate is not a top_level_item, and
3588 - The left_expr of the IN predicate may contain NULL values
3589 (left_expr->maybe_null)
3590 */
3591
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1304 times.
1304 if (tab->has_guarded_conds()) goto no_join_cache;
3592
3593
2/2
✓ Branch 0 taken 503 times.
✓ Branch 1 taken 801 times.
1304 if (tab->table()->covering_keys.is_set(tab->ref().key))
3594 503 join_cache_flags |= HA_MRR_INDEX_ONLY;
3595 1304 rows = tab->table()->file->multi_range_read_info(
3596
1/2
✓ Branch 0 taken 1304 times.
✗ Branch 1 not taken.
1304 tab->ref().key, 10, 20, &bufsz, &join_cache_flags, &cost);
3597 /*
3598 Cannot use BKA if
3599 1. MRR scan cannot be performed, or
3600 2. MRR default implementation is used, or
3601 3. HA_MRR_NO_ASSOCIATION flag is set
3602 */
3603
1/2
✓ Branch 0 taken 1304 times.
✗ Branch 1 not taken.
1304 if ((rows == HA_POS_ERROR) || // 1
3604
2/2
✓ Branch 0 taken 226 times.
✓ Branch 1 taken 1078 times.
1304 (join_cache_flags & HA_MRR_USE_DEFAULT_IMPL) || // 2
3605
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 226 times.
226 (join_cache_flags & HA_MRR_NO_ASSOCIATION)) // 3
3606 1078 goto no_join_cache;
3607
3608 226 tab->set_use_join_cache(JOIN_CACHE::ALG_BKA);
3609
3610 226 tab->join_cache_flags = join_cache_flags;
3611 226 return false;
3612 default:;
3613 }
3614
3615 1892244 no_join_cache:
3616
1/2
✓ Branch 0 taken 1892240 times.
✗ Branch 1 not taken.
1892244 revise_cache_usage(tab);
3617 1892240 tab->set_use_join_cache(JOIN_CACHE::ALG_NONE);
3618 1892243 return false;
3619 }
3620
3621 /*****************************************************************************
3622 Make some simple condition optimization:
3623 If there is a test 'field = const' change all refs to 'field' to 'const'
3624 Remove all dummy tests 'item = item', 'const op const'.
3625 Remove all 'item is NULL', when item can never be null!
3626 Return in cond_value false if condition is impossible (1 = 2)
3627 *****************************************************************************/
3628
3629 class COND_CMP : public ilink<COND_CMP> {
3630 public:
3631 24 static void *operator new(size_t size) { return (*THR_MALLOC)->Alloc(size); }
3632 static void operator delete(void *ptr [[maybe_unused]],
3633 size_t size [[maybe_unused]]) {
3634 TRASH(ptr, size);
3635 }
3636
3637 Item *and_level;
3638 Item_func *cmp_func;
3639 24 COND_CMP(Item *a, Item_func *b) : and_level(a), cmp_func(b) {}
3640 };
3641
3642 9381717 Item_equal *find_item_equal(COND_EQUAL *cond_equal,
3643 const Item_field *item_field, bool *inherited_fl) {
3644 9381717 Item_equal *item = nullptr;
3645 9381717 bool in_upper_level = false;
3646
2/2
✓ Branch 0 taken 10388239 times.
✓ Branch 1 taken 7841763 times.
18230002 while (cond_equal) {
3647
1/2
✓ Branch 0 taken 10388292 times.
✗ Branch 1 not taken.
10388239 List_iterator_fast<Item_equal> li(cond_equal->current_level);
3648
2/2
✓ Branch 0 taken 21881057 times.
✓ Branch 1 taken 8848285 times.
30729351 while ((item = li++)) {
3649
3/4
✓ Branch 0 taken 21881142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1540083 times.
✓ Branch 3 taken 20341059 times.
21881057 if (item->contains(item_field->field)) goto finish;
3650 }
3651 8848285 in_upper_level = true;
3652 8848285 cond_equal = cond_equal->upper_levels;
3653 }
3654 7841763 in_upper_level = false;
3655 9381846 finish:
3656 9381846 *inherited_fl = in_upper_level;
3657 9381846 return item;
3658 }
3659
3660 /**
3661 Get the best field substitution for a given field.
3662
3663 If the field is member of a multiple equality, look up that equality
3664 and return the most appropriate field. Usually this is the equivalenced
3665 field belonging to the outer-most table in the join order, but
3666 @see Item_field::get_subst_item() for details.
3667 Otherwise, return the same field.
3668
3669 @param item_field The field that we are seeking a substitution for.
3670 @param cond_equal multiple equalities to search in
3671
3672 @return The substituted field.
3673 */
3674
3675 1813516 Item_field *get_best_field(Item_field *item_field, COND_EQUAL *cond_equal) {
3676 bool dummy;
3677
1/2
✓ Branch 0 taken 1813534 times.
✗ Branch 1 not taken.
1813516 Item_equal *item_eq = find_item_equal(cond_equal, item_field, &dummy);
3678
2/2
✓ Branch 0 taken 411915 times.
✓ Branch 1 taken 1401619 times.
1813534 if (!item_eq) return item_field;
3679
3680
1/2
✓ Branch 0 taken 1401621 times.
✗ Branch 1 not taken.
1401619 return item_eq->get_subst_item(item_field);
3681 }
3682
3683 /**
3684 Check whether an equality can be used to build multiple equalities.
3685
3686 This function first checks whether the equality (left_item=right_item)
3687 is a simple equality i.e. one that equates a field with another field
3688 or a constant (field=field_item or field=const_item).
3689 If this is the case the function looks for a multiple equality
3690 in the lists referenced directly or indirectly by cond_equal inferring
3691 the given simple equality. If it doesn't find any, it builds a multiple
3692 equality that covers the predicate, i.e. the predicate can be inferred
3693 from this multiple equality.
3694 The built multiple equality could be obtained in such a way:
3695 create a binary multiple equality equivalent to the predicate, then
3696 merge it, if possible, with one of old multiple equalities.
3697 This guarantees that the set of multiple equalities covering equality
3698 predicates will be minimal.
3699
3700 EXAMPLE:
3701 For the where condition
3702 @code
3703 WHERE a=b AND b=c AND
3704 (b=2 OR f=e)
3705 @endcode
3706 the check_equality will be called for the following equality
3707 predicates a=b, b=c, b=2 and f=e.
3708 - For a=b it will be called with *cond_equal=(0,[]) and will transform
3709 *cond_equal into (0,[Item_equal(a,b)]).
3710 - For b=c it will be called with *cond_equal=(0,[Item_equal(a,b)])
3711 and will transform *cond_equal into CE=(0,[Item_equal(a,b,c)]).
3712 - For b=2 it will be called with *cond_equal=(ptr(CE),[])
3713 and will transform *cond_equal into (ptr(CE),[Item_equal(2,a,b,c)]).
3714 - For f=e it will be called with *cond_equal=(ptr(CE), [])
3715 and will transform *cond_equal into (ptr(CE),[Item_equal(f,e)]).
3716
3717 @note
3718 Now only fields that have the same type definitions (verified by
3719 the Field::eq_def method) are placed to the same multiple equalities.
3720 Because of this some equality predicates are not eliminated and
3721 can be used in the constant propagation procedure.
3722 We could weaken the equality test as soon as at least one of the
3723 equal fields is to be equal to a constant. It would require a
3724 more complicated implementation: we would have to store, in
3725 general case, its own constant for each fields from the multiple
3726 equality. But at the same time it would allow us to get rid
3727 of constant propagation completely: it would be done by the call
3728 to build_equal_items_for_cond.
3729
3730 The implementation does not follow exactly the above rules to
3731 build a new multiple equality for the equality predicate.
3732 If it processes the equality of the form field1=field2, it
3733 looks for multiple equalities me1 containing field1 and me2 containing
3734 field2. If only one of them is found the function expands it with
3735 the lacking field. If multiple equalities for both fields are
3736 found they are merged. If both searches fail a new multiple equality
3737 containing just field1 and field2 is added to the existing
3738 multiple equalities.
3739 If the function processes the predicate of the form field1=const,
3740 it looks for a multiple equality containing field1. If found, the
3741 function checks the constant of the multiple equality. If the value
3742 is unknown, it is setup to const. Otherwise the value is compared with
3743 const and the evaluation of the equality predicate is performed.
3744 When expanding/merging equality predicates from the upper levels
3745 the function first copies them for the current level. It looks
3746 acceptable, as this happens rarely. The implementation without
3747 copying would be much more complicated.
3748
3749 @param thd Thread handler
3750 @param left_item left term of the equality to be checked
3751 @param right_item right term of the equality to be checked
3752 @param item equality item if the equality originates from a condition
3753 predicate, 0 if the equality is the result of row
3754 elimination
3755 @param cond_equal multiple equalities that must hold together with the
3756 equality
3757 @param[out] simple_equality
3758 true if the predicate is a simple equality predicate
3759 to be used for building multiple equalities
3760 false otherwise
3761
3762 @returns false if success, true if error
3763 */
3764
3765 5933255 static bool check_simple_equality(THD *thd, Item *left_item, Item *right_item,
3766 Item *item, COND_EQUAL *cond_equal,
3767 bool *simple_equality) {
3768 5933255 *simple_equality = false;
3769
3770
4/4
✓ Branch 0 taken 299244 times.
✓ Branch 1 taken 5634089 times.
✓ Branch 2 taken 299101 times.
✓ Branch 3 taken 5634229 times.
6232496 if (left_item->type() == Item::REF_ITEM &&
3771
2/2
✓ Branch 0 taken 299095 times.
✓ Branch 1 taken 146 times.
299244 down_cast<Item_ref *>(left_item)->ref_type() == Item_ref::VIEW_REF) {
3772
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 299100 times.
299101 if (down_cast<Item_ref *>(left_item)->is_outer_reference()) return false;
3773 299100 left_item = left_item->real_item();
3774 }
3775
4/4
✓ Branch 0 taken 7748 times.
✓ Branch 1 taken 5925533 times.
✓ Branch 2 taken 7679 times.
✓ Branch 3 taken 5925627 times.
5941107 if (right_item->type() == Item::REF_ITEM &&
3776
2/2
✓ Branch 0 taken 7679 times.
✓ Branch 1 taken 94 times.
7748 down_cast<Item_ref *>(right_item)->ref_type() == Item_ref::VIEW_REF) {
3777
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 7667 times.
7679 if (down_cast<Item_ref *>(right_item)->is_outer_reference()) return false;
3778 7667 right_item = right_item->real_item();
3779 }
3780 const Item_field *left_item_field, *right_item_field;
3781
3782 5933294 if (left_item->type() == Item::FIELD_ITEM &&
3783
4/4
✓ Branch 0 taken 2095652 times.
✓ Branch 1 taken 3778655 times.
✓ Branch 2 taken 2095647 times.
✓ Branch 3 taken 1 times.
7969939 right_item->type() == Item::FIELD_ITEM &&
3784
1/2
✓ Branch 0 taken 2095654 times.
✗ Branch 1 not taken.
4191302 (left_item_field = down_cast<const Item_field *>(left_item)) &&
3785 2095647 (right_item_field = down_cast<const Item_field *>(right_item)) &&
3786
8/8
✓ Branch 0 taken 5874291 times.
✓ Branch 1 taken 59001 times.
✓ Branch 2 taken 2095502 times.
✓ Branch 3 taken 152 times.
✓ Branch 4 taken 2093097 times.
✓ Branch 5 taken 2405 times.
✓ Branch 6 taken 2093099 times.
✓ Branch 7 taken 3840208 times.
11807598 !left_item_field->depended_from && !right_item_field->depended_from) {
3787 /* The predicate the form field1=field2 is processed */
3788
3789 2093099 const Field *const left_field = left_item_field->field;
3790 2093099 const Field *const right_field = right_item_field->field;
3791
3792
3/4
✓ Branch 0 taken 2093094 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44699 times.
✓ Branch 3 taken 2048395 times.
2093099 if (!left_field->eq_def(right_field)) return false;
3793
3794 /* Search for multiple equalities containing field1 and/or field2 */
3795 bool left_copyfl, right_copyfl;
3796 Item_equal *left_item_equal =
3797
1/2
✓ Branch 0 taken 2048400 times.
✗ Branch 1 not taken.
2048395 find_item_equal(cond_equal, left_item_field, &left_copyfl);
3798 Item_equal *right_item_equal =
3799
1/2
✓ Branch 0 taken 2048401 times.
✗ Branch 1 not taken.
2048400 find_item_equal(cond_equal, right_item_field, &right_copyfl);
3800
3801 /* As (NULL=NULL) != TRUE we can't just remove the predicate f=f */
3802
3/4
✓ Branch 0 taken 2048385 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 174 times.
✓ Branch 3 taken 2048211 times.
2048401 if (left_field->eq(right_field)) /* f = f */
3803 {
3804 174 *simple_equality =
3805
6/6
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 152 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 21 times.
174 !((left_field->is_nullable() || left_field->table->is_nullable()) &&
3806 !left_item_equal);
3807 174 return false;
3808 }
3809
3810
4/4
✓ Branch 0 taken 116151 times.
✓ Branch 1 taken 1932060 times.
✓ Branch 2 taken 59 times.
✓ Branch 3 taken 116092 times.
2048211 if (left_item_equal && left_item_equal == right_item_equal) {
3811 /*
3812 The equality predicate is inference of one of the existing
3813 multiple equalities, i.e the condition is already covered
3814 by upper level equalities
3815 */
3816 59 *simple_equality = true;
3817 59 return false;
3818 }
3819
3820 /* Copy the found multiple equalities at the current level if needed */
3821
2/2
✓ Branch 0 taken 114355 times.
✓ Branch 1 taken 1933797 times.
2048152 if (left_copyfl) {
3822 /* left_item_equal of an upper level contains left_item */
3823
2/4
✓ Branch 0 taken 114352 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114357 times.
✗ Branch 3 not taken.
114355 left_item_equal = new Item_equal(left_item_equal);
3824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114357 times.
114357 if (left_item_equal == nullptr) return true;
3825
1/2
✓ Branch 0 taken 114351 times.
✗ Branch 1 not taken.
114357 cond_equal->current_level.push_back(left_item_equal);
3826 }
3827
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 2048009 times.
2048148 if (right_copyfl) {
3828 /* right_item_equal of an upper level contains right_item */
3829
2/4
✓ Branch 0 taken 139 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 139 times.
✗ Branch 3 not taken.
139 right_item_equal = new Item_equal(right_item_equal);
3830
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139 times.
139 if (right_item_equal == nullptr) return true;
3831
1/2
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
139 cond_equal->current_level.push_back(right_item_equal);
3832 }
3833
3834
2/2
✓ Branch 0 taken 116087 times.
✓ Branch 1 taken 1932045 times.
2048132 if (left_item_equal) {
3835 /* left item was found in the current or one of the upper levels */
3836
2/2
✓ Branch 0 taken 116003 times.
✓ Branch 1 taken 84 times.
116087 if (!right_item_equal)
3837
1/2
✓ Branch 0 taken 116006 times.
✗ Branch 1 not taken.
116003 left_item_equal->add(down_cast<Item_field *>(right_item));
3838 else {
3839 /* Merge two multiple equalities forming a new one */
3840
2/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
84 if (left_item_equal->merge(thd, right_item_equal)) return true;
3841 /* Remove the merged multiple equality from the list */
3842
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 List_iterator<Item_equal> li(cond_equal->current_level);
3843
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 84 times.
156 while ((li++) != right_item_equal)
3844 ;
3845
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 li.remove();
3846 }
3847 } else {
3848 /* left item was not found neither the current nor in upper levels */
3849
2/2
✓ Branch 0 taken 21444 times.
✓ Branch 1 taken 1910601 times.
1932045 if (right_item_equal) {
3850
1/2
✓ Branch 0 taken 21445 times.
✗ Branch 1 not taken.
21444 right_item_equal->add(down_cast<Item_field *>(left_item));
3851 } else {
3852 /* None of the fields was found in multiple equalities */
3853 Item_equal *item_equal =
3854 1910601 new Item_equal(down_cast<Item_field *>(left_item),
3855
2/4
✓ Branch 0 taken 1910623 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1910626 times.
✗ Branch 3 not taken.
1910620 down_cast<Item_field *>(right_item));
3856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1910626 times.
1910626 if (item_equal == nullptr) return true;
3857
1/2
✓ Branch 0 taken 1910628 times.
✗ Branch 1 not taken.
1910626 cond_equal->current_level.push_back(item_equal);
3858 }
3859 }
3860 2048163 *simple_equality = true;
3861 2048163 return false;
3862 }
3863
3864 {
3865 /* The predicate of the form field=const/const=field is processed */
3866 3840208 Item *const_item = nullptr;
3867 3840208 Item_field *field_item = nullptr;
3868
1/2
✓ Branch 0 taken 3781212 times.
✗ Branch 1 not taken.
7621396 if (left_item->type() == Item::FIELD_ITEM &&
3869 3781130 (field_item = down_cast<Item_field *>(left_item)) &&
3870
6/6
✓ Branch 0 taken 3781130 times.
✓ Branch 1 taken 59028 times.
✓ Branch 2 taken 3780938 times.
✓ Branch 3 taken 274 times.
✓ Branch 4 taken 3773264 times.
✓ Branch 5 taken 66923 times.
11402255 field_item->depended_from == nullptr &&
3871
2/2
✓ Branch 0 taken 3773259 times.
✓ Branch 1 taken 7650 times.
3780938 right_item->const_for_execution()) {
3872 3773264 const_item = right_item;
3873
1/2
✓ Branch 0 taken 23639 times.
✗ Branch 1 not taken.
90562 } else if (right_item->type() == Item::FIELD_ITEM &&
3874 23639 (field_item = down_cast<Item_field *>(right_item)) &&
3875
6/6
✓ Branch 0 taken 23639 times.
✓ Branch 1 taken 43289 times.
✓ Branch 2 taken 20971 times.
✓ Branch 3 taken 2668 times.
✓ Branch 4 taken 19607 times.
✓ Branch 5 taken 47321 times.
111538 field_item->depended_from == nullptr &&
3876
2/2
✓ Branch 0 taken 19607 times.
✓ Branch 1 taken 1364 times.
20971 left_item->const_for_execution()) {
3877 19607 const_item = left_item;
3878 }
3879
3880 // Don't evaluate subqueries if they are disabled during optimization.
3881
3/4
✓ Branch 0 taken 3792857 times.
✓ Branch 1 taken 47335 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3840233 times.
7633090 if (const_item != nullptr &&
3882
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3792898 times.
3792868 !evaluate_during_optimization(const_item,
3883 3792857 thd->lex->current_query_block()))
3884 return false;
3885
3886 /*
3887 If the constant expression contains a reference to the field
3888 (for example, a = (a IS NULL)), we don't want to replace the
3889 field with the constant expression as it makes the predicates
3890 more complex and may introduce cycles in the Item tree.
3891 */
3892
3/4
✓ Branch 0 taken 3792909 times.
✓ Branch 1 taken 47324 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3840165 times.
7633074 if (const_item != nullptr &&
3893
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3792841 times.
3792891 const_item->walk(&Item::find_field_processor, enum_walk::POSTFIX,
3894 3792909 pointer_cast<uchar *>(field_item->field)))
3895 return false;
3896
3897
6/6
✓ Branch 0 taken 3792873 times.
✓ Branch 1 taken 47292 times.
✓ Branch 2 taken 3782749 times.
✓ Branch 3 taken 10150 times.
✓ Branch 4 taken 3782744 times.
✓ Branch 5 taken 57447 times.
3840165 if (const_item && field_item->result_type() == const_item->result_type()) {
3898
3/4
✓ Branch 0 taken 3782796 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 957233 times.
✓ Branch 3 taken 2825563 times.
3782744 if (field_item->result_type() == STRING_RESULT) {
3899
1/2
✓ Branch 0 taken 957235 times.
✗ Branch 1 not taken.
957233 const CHARSET_INFO *cs = field_item->field->charset();
3900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 957235 times.
957235 if (!item) {
3901 Item_func_eq *const eq_item = new Item_func_eq(left_item, right_item);
3902 if (eq_item == nullptr || eq_item->set_cmp_func()) return true;
3903 eq_item->quick_fix_field();
3904 item = eq_item;
3905 }
3906
5/6
✓ Branch 0 taken 957234 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 956232 times.
✓ Branch 3 taken 1002 times.
✓ Branch 4 taken 311473 times.
✓ Branch 5 taken 645752 times.
1913458 if ((cs != down_cast<Item_func *>(item)->compare_collation()) ||
3907
3/4
✓ Branch 0 taken 956223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 310471 times.
✓ Branch 3 taken 645752 times.
956232 !cs->coll->propagate(cs, nullptr, 0))
3908 311473 return false;
3909 }
3910
3911 bool copyfl;
3912
1/2
✓ Branch 0 taken 3471324 times.
✗ Branch 1 not taken.
3471315 Item_equal *item_equal = find_item_equal(cond_equal, field_item, &copyfl);
3913
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 3471160 times.
3471324 if (copyfl) {
3914
2/4
✓ Branch 0 taken 164 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 164 times.
✗ Branch 3 not taken.
164 item_equal = new Item_equal(item_equal);
3915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 164 times.
164 if (item_equal == nullptr) return true;
3916
1/2
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
164 cond_equal->current_level.push_back(item_equal);
3917 }
3918
2/2
✓ Branch 0 taken 696 times.
✓ Branch 1 taken 3470611 times.
3471307 if (item_equal) {
3919 /*
3920 The flag cond_false will be set to 1 after this, if item_equal
3921 already contains a constant and its value is not equal to
3922 the value of const_item.
3923 */
3924
3/4
✓ Branch 0 taken 696 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 695 times.
696 if (item_equal->add(thd, const_item, field_item)) return true;
3925 } else {
3926
2/4
✓ Branch 0 taken 3470613 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3470580 times.
✗ Branch 3 not taken.
3470611 item_equal = new Item_equal(const_item, field_item);
3927
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3470580 times.
3470580 if (item_equal == nullptr) return true;
3928
1/2
✓ Branch 0 taken 3470624 times.
✗ Branch 1 not taken.
3470580 cond_equal->current_level.push_back(item_equal);
3929 }
3930 3471319 *simple_equality = true;
3931 3471319 return false;
3932 }
3933 }
3934 57447 return false;
3935 }
3936
3937 /**
3938 Convert row equalities into a conjunction of regular equalities.
3939
3940 The function converts a row equality of the form (E1,...,En)=(E'1,...,E'n)
3941 into a list of equalities E1=E'1,...,En=E'n. For each of these equalities
3942 Ei=E'i the function checks whether it is a simple equality or a row
3943 equality. If it is a simple equality it is used to expand multiple
3944 equalities of cond_equal. If it is a row equality it converted to a
3945 sequence of equalities between row elements. If Ei=E'i is neither a
3946 simple equality nor a row equality the item for this predicate is added
3947 to eq_list.
3948
3949 @param thd thread handle
3950 @param left_row left term of the row equality to be processed
3951 @param right_row right term of the row equality to be processed
3952 @param cond_equal multiple equalities that must hold together with the
3953 predicate
3954 @param eq_list results of conversions of row equalities that are not
3955 simple enough to form multiple equalities
3956 @param[out] simple_equality
3957 true if the row equality is composed of only
3958 simple equalities.
3959
3960 @returns false if conversion succeeded, true if any error.
3961 */
3962
3963 100 static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
3964 COND_EQUAL *cond_equal, List<Item> *eq_list,
3965 bool *simple_equality) {
3966 100 *simple_equality = false;
3967 100 uint n = left_row->cols();
3968
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 100 times.
324 for (uint i = 0; i < n; i++) {
3969 bool is_converted;
3970
1/2
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
224 Item *left_item = left_row->element_index(i);
3971
1/2
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
224 Item *right_item = right_row->element_index(i);
3972
3/6
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 224 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 224 times.
224 if (left_item->type() == Item::ROW_ITEM &&
3973 right_item->type() == Item::ROW_ITEM) {
3974 if (check_row_equality(thd, down_cast<Item_row *>(left_item),
3975 down_cast<Item_row *>(right_item), cond_equal,
3976 eq_list, &is_converted))
3977 return true;
3978 if (!is_converted) thd->lex->current_query_block()->cond_count++;
3979 } else {
3980
2/4
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 224 times.
224 if (check_simple_equality(thd, left_item, right_item, nullptr, cond_equal,
3981 &is_converted))
3982 return true;
3983 224 thd->lex->current_query_block()->cond_count++;
3984 }
3985
3986
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 206 times.
224 if (!is_converted) {
3987
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
18 Item_func_eq *const eq_item = new Item_func_eq(left_item, right_item);
3988
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (eq_item == nullptr) return true;
3989
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
18 if (eq_item->set_cmp_func()) {
3990 // Failed to create cmp func -> not only simple equalitities
3991 return true;
3992 }
3993 18 eq_item->quick_fix_field();
3994
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 eq_list->push_back(eq_item);
3995 }
3996 }
3997 100 *simple_equality = true;
3998 100 return false;
3999 }
4000
4001 /**
4002 Eliminate row equalities and form multiple equalities predicates.
4003
4004 This function checks whether the item is a simple equality
4005 i.e. the one that equates a field with another field or a constant
4006 (field=field_item or field=constant_item), or, a row equality.
4007 For a simple equality the function looks for a multiple equality
4008 in the lists referenced directly or indirectly by cond_equal inferring
4009 the given simple equality. If it doesn't find any, it builds/expands
4010 multiple equality that covers the predicate.
4011 Row equalities are eliminated substituted for conjunctive regular
4012 equalities which are treated in the same way as original equality
4013 predicates.
4014
4015 @param thd thread handle
4016 @param item predicate to process
4017 @param cond_equal multiple equalities that must hold together with the
4018 predicate
4019 @param eq_list results of conversions of row equalities that are not
4020 simple enough to form multiple equalities
4021 @param[out] equality
4022 true if re-writing rules have been applied
4023 false otherwise, i.e.
4024 if the predicate is not an equality, or
4025 if the equality is neither a simple nor a row equality
4026
4027 @returns false if success, true if error
4028
4029 @note If the equality was created by IN->EXISTS, it may be removed later by
4030 subquery materialization. So we don't mix this possibly temporary equality
4031 with others; if we let it go into a multiple-equality (Item_equal), then we
4032 could not remove it later. There is however an exception: if the outer
4033 expression is a constant, it is safe to leave the equality even in
4034 materialization; all it can do is preventing NULL/FALSE distinction but if
4035 such distinction mattered the equality would be in a triggered condition so
4036 we would not come to this function. And injecting constants is good because
4037 it makes the materialized table smaller.
4038 */
4039
4040 8891305 static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
4041 List<Item> *eq_list, bool *equality) {
4042 8891305 *equality = false;
4043
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8891397 times.
8891305 assert(item->is_bool_func());
4044 Item_func *item_func;
4045
4/4
✓ Branch 0 taken 8885794 times.
✓ Branch 1 taken 5588 times.
✓ Branch 2 taken 5933801 times.
✓ Branch 3 taken 2957503 times.
17777113 if (item->type() == Item::FUNC_ITEM &&
4046
2/2
✓ Branch 0 taken 5933756 times.
✓ Branch 1 taken 2951960 times.
8885794 (item_func = down_cast<Item_func *>(item))->functype() ==
4047 Item_func::EQ_FUNC) {
4048 5933801 Item *left_item = item_func->arguments()[0];
4049 5933820 Item *right_item = item_func->arguments()[1];
4050
4051
6/6
✓ Branch 0 taken 740 times.
✓ Branch 1 taken 5932999 times.
✓ Branch 2 taken 604 times.
✓ Branch 3 taken 136 times.
✓ Branch 4 taken 604 times.
✓ Branch 5 taken 5933135 times.
5933840 if (item->created_by_in2exists() && !left_item->const_item())
4052 604 return false; // See note above
4053
4054
4/4
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 5933011 times.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 5933044 times.
5933268 if (left_item->type() == Item::ROW_ITEM &&
4055
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 33 times.
126 right_item->type() == Item::ROW_ITEM) {
4056 100 thd->lex->current_query_block()->cond_count--;
4057 100 return check_row_equality(thd, down_cast<Item_row *>(left_item),
4058 down_cast<Item_row *>(right_item), cond_equal,
4059 100 eq_list, equality);
4060 } else
4061 5933044 return check_simple_equality(thd, left_item, right_item, item, cond_equal,
4062 5933096 equality);
4063 }
4064
4065 2957503 return false;
4066 }
4067
4068 /**
4069 Replace all equality predicates in a condition by multiple equality items.
4070
4071 At each 'and' level the function detects items for equality predicates
4072 and replaces them by a set of multiple equality items of class Item_equal,
4073 taking into account inherited equalities from upper levels.
4074 If an equality predicate is used not in a conjunction it's just
4075 replaced by a multiple equality predicate.
4076 For each 'and' level the function set a pointer to the inherited
4077 multiple equalities in the cond_equal field of the associated
4078 object of the type Item_cond_and.
4079 The function also traverses the cond tree and for each field reference
4080 sets a pointer to the multiple equality item containing the field, if there
4081 is any. If this multiple equality equates fields to a constant the
4082 function replaces the field reference by the constant in the cases
4083 when the field is not of a string type or when the field reference is
4084 just an argument of a comparison predicate.
4085 The function also determines the maximum number of members in
4086 equality lists of each Item_cond_and object assigning it to
4087 thd->lex->current_query_block()->max_equal_elems.
4088
4089 @note
4090 Multiple equality predicate =(f1,..fn) is equivalent to the conjunction of
4091 f1=f2, .., fn-1=fn. It substitutes any inference from these
4092 equality predicates that is equivalent to the conjunction.
4093 Thus, =(a1,a2,a3) can substitute for ((a1=a3) AND (a2=a3) AND (a2=a1)) as
4094 it is equivalent to ((a1=a2) AND (a2=a3)).
4095 The function always makes a substitution of all equality predicates occurred
4096 in a conjunction for a minimal set of multiple equality predicates.
4097 This set can be considered as a canonical representation of the
4098 sub-conjunction of the equality predicates.
4099 E.g. (t1.a=t2.b AND t2.b>5 AND t1.a=t3.c) is replaced by
4100 (=(t1.a,t2.b,t3.c) AND t2.b>5), not by
4101 (=(t1.a,t2.b) AND =(t1.a,t3.c) AND t2.b>5);
4102 while (t1.a=t2.b AND t2.b>5 AND t3.c=t4.d) is replaced by
4103 (=(t1.a,t2.b) AND =(t3.c=t4.d) AND t2.b>5),
4104 but if additionally =(t4.d,t2.b) is inherited, it
4105 will be replaced by (=(t1.a,t2.b,t3.c,t4.d) AND t2.b>5)
4106
4107 The function performs the substitution in a recursive descent of
4108 the condition tree, passing to the next AND level a chain of multiple
4109 equality predicates which have been built at the upper levels.
4110 The Item_equal items built at the level are attached to other
4111 non-equality conjuncts as a sublist. The pointer to the inherited
4112 multiple equalities is saved in the and condition object (Item_cond_and).
4113 This chain allows us for any field reference occurrence to easily find a
4114 multiple equality that must be held for this occurrence.
4115 For each AND level we do the following:
4116 - scan it for all equality predicate (=) items
4117 - join them into disjoint Item_equal() groups
4118 - process the included OR conditions recursively to do the same for
4119 lower AND levels.
4120
4121 We need to do things in this order as lower AND levels need to know about
4122 all possible Item_equal objects in upper levels.
4123
4124 @param thd thread handle
4125 @param cond condition(expression) where to make replacement
4126 @param[out] retcond returned condition
4127 @param inherited path to all inherited multiple equality items
4128 @param do_inherit whether or not to inherit equalities from other parts
4129 of the condition
4130
4131 @returns false if success, true if error
4132 */
4133
4134 4707341 static bool build_equal_items_for_cond(THD *thd, Item *cond, Item **retcond,
4135 COND_EQUAL *inherited, bool do_inherit) {
4136 Item_equal *item_equal;
4137
1/2
✓ Branch 0 taken 4707391 times.
✗ Branch 1 not taken.
4707341 COND_EQUAL cond_equal;
4138 4707391 cond_equal.upper_levels = inherited;
4139
2/4
✓ Branch 0 taken 4707353 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4707353 times.
4707391 assert(cond->is_bool_func());
4140
2/4
✓ Branch 0 taken 4707440 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4707440 times.
4707353 if (check_stack_overrun(thd, STACK_MIN_SIZE, nullptr))
4141 return true; // Fatal error flag is set!
4142
4143
1/2
✓ Branch 0 taken 4707377 times.
✗ Branch 1 not taken.
4707440 const enum Item::Type cond_type = cond->type();
4144
2/2
✓ Branch 0 taken 1959456 times.
✓ Branch 1 taken 2747921 times.
4707377 if (cond_type == Item::COND_ITEM) {
4145 1959456 List<Item> eq_list;
4146 1959451 Item_cond *const item_cond = down_cast<Item_cond *>(cond);
4147
1/2
✓ Branch 0 taken 1959450 times.
✗ Branch 1 not taken.
1959447 const bool and_level = item_cond->functype() == Item_func::COND_AND_FUNC;
4148 1959450 List<Item> *args = item_cond->argument_list();
4149
4150
1/2
✓ Branch 0 taken 1959456 times.
✗ Branch 1 not taken.
1959456 List_iterator<Item> li(*args);
4151 Item *item;
4152
4153
2/2
✓ Branch 0 taken 1929778 times.
✓ Branch 1 taken 29678 times.
1959456 if (and_level) {
4154 /*
4155 Retrieve all conjuncts of this level detecting the equality
4156 that are subject to substitution by multiple equality items and
4157 removing each such predicate from the conjunction after having
4158 found/created a multiple equality whose inference the predicate is.
4159 */
4160
2/2
✓ Branch 0 taken 6143521 times.
✓ Branch 1 taken 1929775 times.
8073294 while ((item = li++)) {
4161 /*
4162 PS/SP note: we can safely remove a node from AND-OR
4163 structure here because it's restored before each
4164 re-execution of any prepared statement/stored procedure.
4165 */
4166 bool equality;
4167
3/4
✓ Branch 0 taken 6143511 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 6143510 times.
6143521 if (check_equality(thd, item, &cond_equal, &eq_list, &equality))
4168 1 return true;
4169
3/4
✓ Branch 0 taken 4617641 times.
✓ Branch 1 taken 1525869 times.
✓ Branch 2 taken 4617647 times.
✗ Branch 3 not taken.
6143510 if (equality) li.remove();
4170 }
4171
4172 /*
4173 Check if we eliminated all the predicates of the level, e.g.
4174 (a=a AND b=b AND a=a).
4175 */
4176
4/4
✓ Branch 0 taken 1264023 times.
✓ Branch 1 taken 665752 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 1263978 times.
1929775 if (!args->elements && !cond_equal.current_level.elements &&
4177
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 !eq_list.elements) {
4178
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
90 *retcond = new Item_func_true();
4179 45 return *retcond == nullptr;
4180 }
4181
4182
1/2
✓ Branch 0 taken 1929728 times.
✗ Branch 1 not taken.
1929730 List_iterator_fast<Item_equal> it(cond_equal.current_level);
4183
2/2
✓ Branch 0 taken 4593795 times.
✓ Branch 1 taken 1929730 times.
6523524 while ((item_equal = it++)) {
4184
2/4
✓ Branch 0 taken 4593780 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4593780 times.
4593795 if (item_equal->resolve_type(thd)) return true;
4185
1/2
✓ Branch 0 taken 4593802 times.
✗ Branch 1 not taken.
4593780 item_equal->update_used_tables();
4186 9187584 thd->lex->current_query_block()->max_equal_elems =
4187 4593802 std::max(thd->lex->current_query_block()->max_equal_elems,
4188
1/2
✓ Branch 0 taken 4593801 times.
✗ Branch 1 not taken.
9187598 item_equal->members());
4189 }
4190
4191 1929730 Item_cond_and *const item_cond_and = down_cast<Item_cond_and *>(cond);
4192
1/2
✓ Branch 0 taken 1929721 times.
✗ Branch 1 not taken.
1929723 item_cond_and->cond_equal = cond_equal;
4193 1929721 inherited = &item_cond_and->cond_equal;
4194 }
4195 /*
4196 Make replacement of equality predicates for lower levels
4197 of the condition expression.
4198 */
4199 1959399 li.rewind();
4200
2/2
✓ Branch 0 taken 2545553 times.
✓ Branch 1 taken 1959407 times.
4504947 while ((item = li++)) {
4201 Item *new_item;
4202
2/4
✓ Branch 0 taken 2545543 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2545543 times.
2545553 if (build_equal_items_for_cond(thd, item, &new_item, inherited,
4203 do_inherit))
4204 return true;
4205
2/2
✓ Branch 0 taken 10734 times.
✓ Branch 1 taken 2534809 times.
2545543 if (new_item != item) {
4206 /* This replacement happens only for standalone equalities */
4207 /*
4208 This is ok with PS/SP as the replacement is done for
4209 arguments of an AND/OR item, which are restored for each
4210 execution of PS/SP.
4211 */
4212 10734 li.replace(new_item);
4213 }
4214 }
4215
2/2
✓ Branch 0 taken 1929732 times.
✓ Branch 1 taken 29675 times.
1959407 if (and_level) {
4216
1/2
✓ Branch 0 taken 1929724 times.
✗ Branch 1 not taken.
1929732 args->concat(&eq_list);
4217
1/2
✓ Branch 0 taken 1929736 times.
✗ Branch 1 not taken.
1929724 args->concat((List<Item> *)&cond_equal.current_level);
4218 }
4219
3/4
✓ Branch 0 taken 2747904 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2747809 times.
✓ Branch 3 taken 95 times.
2747921 } else if (cond->type() == Item::FUNC_ITEM) {
4220 2747809 List<Item> eq_list;
4221 /*
4222 If an equality predicate forms the whole and level,
4223 we call it standalone equality and it's processed here.
4224 E.g. in the following where condition
4225 WHERE a=5 AND (b=5 or a=c)
4226 (b=5) and (a=c) are standalone equalities.
4227 In general we can't leave alone standalone eqalities:
4228 for WHERE a=b AND c=d AND (b=c OR d=5)
4229 b=c is replaced by =(a,b,c,d).
4230 */
4231 bool equality;
4232
2/4
✓ Branch 0 taken 2747841 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2747841 times.
2747838 if (check_equality(thd, cond, &cond_equal, &eq_list, &equality))
4233 901901 return true;
4234
2/2
✓ Branch 0 taken 901929 times.
✓ Branch 1 taken 1845912 times.
2747841 if (equality) {
4235 901929 int n = cond_equal.current_level.elements + eq_list.elements;
4236
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 901905 times.
901929 if (n == 0) {
4237
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
48 *retcond = new Item_func_true();
4238 24 return *retcond == nullptr;
4239
2/2
✓ Branch 0 taken 901807 times.
✓ Branch 1 taken 98 times.
901905 } else if (n == 1) {
4240
2/2
✓ Branch 0 taken 901808 times.
✓ Branch 1 taken 7 times.
901807 if ((item_equal = cond_equal.current_level.pop())) {
4241
2/4
✓ Branch 0 taken 901772 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 901772 times.
901808 if (item_equal->resolve_type(thd)) return true;
4242
1/2
✓ Branch 0 taken 901840 times.
✗ Branch 1 not taken.
901772 item_equal->update_used_tables();
4243 1803565 thd->lex->current_query_block()->max_equal_elems =
4244 901765 std::max(thd->lex->current_query_block()->max_equal_elems,
4245
1/2
✓ Branch 0 taken 901751 times.
✗ Branch 1 not taken.
901840 item_equal->members());
4246 901777 *retcond = item_equal;
4247 901777 return false;
4248 }
4249
4250 7 *retcond = eq_list.pop();
4251 return false;
4252 } else {
4253 /*
4254 Here a new AND level must be created. It can happen only
4255 when a row equality is processed as a standalone predicate.
4256 */
4257
2/4
✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
✗ Branch 3 not taken.
98 Item_cond_and *and_cond = new Item_cond_and(eq_list);
4258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if (and_cond == nullptr) return true;
4259
4260 100 and_cond->quick_fix_field();
4261 100 List<Item> *args = and_cond->argument_list();
4262
1/2
✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
100 List_iterator_fast<Item_equal> it(cond_equal.current_level);
4263
2/2
✓ Branch 0 taken 206 times.
✓ Branch 1 taken 100 times.
306 while ((item_equal = it++)) {
4264
2/4
✓ Branch 0 taken 206 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 206 times.
206 if (item_equal->resolve_type(thd)) return true;
4265
1/2
✓ Branch 0 taken 206 times.
✗ Branch 1 not taken.
206 item_equal->update_used_tables();
4266 412 thd->lex->current_query_block()->max_equal_elems =
4267 206 std::max(thd->lex->current_query_block()->max_equal_elems,
4268
1/2
✓ Branch 0 taken 206 times.
✗ Branch 1 not taken.
412 item_equal->members());
4269 }
4270
1/2
✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
100 and_cond->cond_equal = cond_equal;
4271
1/2
✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
100 args->concat((List<Item> *)&cond_equal.current_level);
4272
4273 100 *retcond = and_cond;
4274 100 return false;
4275 }
4276 }
4277
4278
2/2
✓ Branch 0 taken 1845898 times.
✓ Branch 1 taken 14 times.
1845912 if (do_inherit) {
4279 /*
4280 For each field reference in cond, not from equal item predicates,
4281 set a pointer to the multiple equality it belongs to (if there is any)
4282 as soon the field is not of a string type or the field reference is
4283 an argument of a comparison predicate.
4284 */
4285 1845898 uchar *is_subst_valid = (uchar *)1;
4286
1/2
✓ Branch 0 taken 1845911 times.
✗ Branch 1 not taken.
1845898 cond = cond->compile(&Item::subst_argument_checker, &is_subst_valid,
4287 &Item::equal_fields_propagator, (uchar *)inherited);
4288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1845911 times.
1845911 if (cond == nullptr) return true;
4289 }
4290
1/2
✓ Branch 0 taken 1845912 times.
✗ Branch 1 not taken.
1845925 cond->update_used_tables();
4291 }
4292 3805418 *retcond = cond;
4293 3805418 return false;
4294 }
4295
4296 /**
4297 Build multiple equalities for a WHERE condition and all join conditions that
4298 inherit these multiple equalities.
4299
4300 The function first applies the build_equal_items_for_cond function
4301 to build all multiple equalities for condition cond utilizing equalities
4302 referred through the parameter inherited. The extended set of
4303 equalities is returned in the structure referred by the cond_equal_ref
4304 parameter. After this the function calls itself recursively for
4305 all join conditions whose direct references can be found in join_list
4306 and who inherit directly the multiple equalities just having built.
4307
4308 @note
4309 The join condition used in an outer join operation inherits all equalities
4310 from the join condition of the embedding join, if there is any, or
4311 otherwise - from the where condition.
4312 This fact is not obvious, but presumably can be proved.
4313 Consider the following query:
4314 @code
4315 SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t2.a=t4.a
4316 WHERE t1.a=t2.a;
4317 @endcode
4318 If the join condition in the query inherits =(t1.a,t2.a), then we
4319 can build the multiple equality =(t1.a,t2.a,t3.a,t4.a) that infers
4320 the equality t3.a=t4.a. Although the join condition
4321 t1.a=t3.a AND t2.a=t4.a AND t3.a=t4.a is not equivalent to the one
4322 in the query the latter can be replaced by the former: the new query
4323 will return the same result set as the original one.
4324
4325 Interesting that multiple equality =(t1.a,t2.a,t3.a,t4.a) allows us
4326 to use t1.a=t3.a AND t3.a=t4.a under the join condition:
4327 @code
4328 SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a
4329 WHERE t1.a=t2.a
4330 @endcode
4331 This query equivalent to:
4332 @code
4333 SELECT * FROM (t1 LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a),t2
4334 WHERE t1.a=t2.a
4335 @endcode
4336 Similarly the original query can be rewritten to the query:
4337 @code
4338 SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t2.a=t4.a AND t3.a=t4.a
4339 WHERE t1.a=t2.a
4340 @endcode
4341 that is equivalent to:
4342 @code
4343 SELECT * FROM (t2 LEFT JOIN (t3,t4)ON t2.a=t4.a AND t3.a=t4.a), t1
4344 WHERE t1.a=t2.a
4345 @endcode
4346 Thus, applying equalities from the where condition we basically
4347 can get more freedom in performing join operations.
4348 Although we don't use this property now, it probably makes sense to use
4349 it in the future.
4350
4351 @param thd Thread handler
4352 @param cond condition to build the multiple equalities for
4353 @param[out] retcond Returned condition
4354 @param inherited path to all inherited multiple equality items
4355 @param do_inherit whether or not to inherit equalities from other
4356 parts of the condition
4357 @param join_list list of join tables that the condition refers to
4358 @param[out] cond_equal_ref pointer to the structure to place built
4359 equalities in
4360
4361 @returns false if success, true if error
4362 */
4363
4364 2165727 bool build_equal_items(THD *thd, Item *cond, Item **retcond,
4365 COND_EQUAL *inherited, bool do_inherit,
4366 mem_root_deque<TABLE_LIST *> *join_list,
4367 COND_EQUAL **cond_equal_ref) {
4368 2165727 COND_EQUAL *cond_equal = nullptr;
4369
4370
2/2
✓ Branch 0 taken 2161787 times.
✓ Branch 1 taken 3940 times.
2165727 if (cond) {
4371
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2161816 times.
2161787 if (build_equal_items_for_cond(thd, cond, &cond, inherited, do_inherit))
4372 1 return true;
4373 2161816 cond->update_used_tables();
4374 // update_used_tables() returns void but can still fail.
4375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2161879 times.
2161889 if (thd->is_error()) return true;
4376
4377 2161879 const enum Item::Type cond_type = cond->type();
4378
4/4
✓ Branch 0 taken 993100 times.
✓ Branch 1 taken 1168750 times.
✓ Branch 2 taken 968989 times.
✓ Branch 3 taken 1192875 times.
3154964 if (cond_type == Item::COND_ITEM &&
4379
2/2
✓ Branch 0 taken 969000 times.
✓ Branch 1 taken 24114 times.
993100 down_cast<Item_cond *>(cond)->functype() == Item_func::COND_AND_FUNC)
4380 968989 cond_equal = &down_cast<Item_cond_and *>(cond)->cond_equal;
4381
4/4
✓ Branch 0 taken 1168600 times.
✓ Branch 1 taken 24275 times.
✓ Branch 2 taken 891174 times.
✓ Branch 3 taken 301652 times.
2361426 else if (cond_type == Item::FUNC_ITEM &&
4382
2/2
✓ Branch 0 taken 891149 times.
✓ Branch 1 taken 277402 times.
1168600 down_cast<Item_func *>(cond)->functype() ==
4383 Item_func::MULT_EQUAL_FUNC) {
4384
2/4
✓ Branch 0 taken 891172 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 891177 times.
✗ Branch 3 not taken.
891174 cond_equal = new (thd->mem_root) COND_EQUAL;
4385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 891177 times.
891177 if (cond_equal == nullptr) return true;
4386 891177 cond_equal->current_level.push_back(down_cast<Item_equal *>(cond));
4387 }
4388 }
4389
2/2
✓ Branch 0 taken 1860186 times.
✓ Branch 1 taken 305621 times.
2165807 if (cond_equal) {
4390 1860186 cond_equal->upper_levels = inherited;
4391 1860186 inherited = cond_equal;
4392 }
4393 2165807 *cond_equal_ref = cond_equal;
4394
4395
2/2
✓ Branch 0 taken 1767371 times.
✓ Branch 1 taken 398436 times.
2165807 if (join_list) {
4396
7/12
✓ Branch 0 taken 1767370 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1767390 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3764314 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3764299 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5531678 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3764290 times.
✓ Branch 11 taken 1767388 times.
5531630 for (TABLE_LIST *table : *join_list) {
4397
2/2
✓ Branch 0 taken 400295 times.
✓ Branch 1 taken 3363967 times.
3764314 if (table->join_cond_optim()) {
4398 400295 mem_root_deque<TABLE_LIST *> *nested_join_list =
4399
2/2
✓ Branch 0 taken 1859 times.
✓ Branch 1 taken 398436 times.
400295 table->nested_join ? &table->nested_join->join_list : nullptr;
4400 Item *join_cond;
4401
2/4
✓ Branch 0 taken 400292 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 400292 times.
400295 if (build_equal_items(thd, table->join_cond_optim(), &join_cond,
4402 inherited, do_inherit, nested_join_list,
4403 &table->cond_equal))
4404 return true;
4405 400292 table->set_join_cond_optim(join_cond);
4406 }
4407 }
4408 }
4409
4410 2165824 *retcond = cond;
4411 2165824 return false;
4412 }
4413
4414 /**
4415 Compare field items by table order in the execution plan.
4416
4417 field1 considered as better than field2 if the table containing
4418 field1 is accessed earlier than the table containing field2.
4419 The function finds out what of two fields is better according
4420 this criteria.
4421
4422 @param field1 first field item to compare
4423 @param field2 second field item to compare
4424 @param table_join_idx index to tables determining table order
4425
4426 @retval
4427 -1 if field1 is better than field2
4428 @retval
4429 1 if field2 is better than field1
4430 @retval
4431 0 otherwise
4432 */
4433
4434 2472480 static int compare_fields_by_table_order(Item_field *field1, Item_field *field2,
4435 JOIN_TAB **table_join_idx) {
4436 2472480 int cmp = 0;
4437 2472480 bool outer_ref = false;
4438
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2472507 times.
2472480 if (field1->is_outer_reference()) {
4439 outer_ref = true;
4440 cmp = -1;
4441 }
4442
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2472506 times.
2472507 if (field2->is_outer_reference()) {
4443 outer_ref = true;
4444 cmp++;
4445 }
4446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2472506 times.
2472506 if (outer_ref) return cmp;
4447
4448 /*
4449 table_join_idx is NULL if this function was not called from JOIN::optimize()
4450 but from e.g. mysql_delete() or mysql_update(). In these cases
4451 there is only one table and both fields belong to it. Example
4452 condition where this is the case: t1.fld1=t1.fld2
4453 */
4454
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 2472440 times.
2472506 if (!table_join_idx) return 0;
4455
4456 // Locate JOIN_TABs thanks to table_join_idx, then compare their index.
4457 2472440 cmp = table_join_idx[field1->table_ref->tableno()]->idx() -
4458 2472434 table_join_idx[field2->table_ref->tableno()]->idx();
4459
4/4
✓ Branch 0 taken 1253849 times.
✓ Branch 1 taken 1218587 times.
✓ Branch 2 taken 1253082 times.
✓ Branch 3 taken 767 times.
2472436 return cmp < 0 ? -1 : (cmp ? 1 : 0);
4460 }
4461
4462 /**
4463 Generate minimal set of simple equalities equivalent to a multiple equality.
4464
4465 The function retrieves the fields of the multiple equality item
4466 item_equal and for each field f:
4467 - if item_equal contains const it generates the equality f=const_item;
4468 - otherwise, if f is not the first field, generates the equality
4469 f=item_equal->get_first().
4470 All generated equality are added to the cond conjunction.
4471
4472 @param thd the session context
4473 @param cond condition to add the generated equality to
4474 @param upper_levels structure to access multiple equality of upper levels
4475 @param item_equal multiple equality to generate simple equality from
4476
4477 @note
4478 Before generating an equality function checks that it has not
4479 been generated for multiple equalities of the upper levels.
4480 E.g. for the following where condition
4481 WHERE a=5 AND ((a=b AND b=c) OR c>4)
4482 the upper level AND condition will contain =(5,a),
4483 while the lower level AND condition will contain =(5,a,b,c).
4484 When splitting =(5,a,b,c) into a separate equality predicates
4485 we should omit 5=a, as we have it already in the upper level.
4486 The following where condition gives us a more complicated case:
4487 WHERE t1.a=t2.b AND t3.c=t4.d AND (t2.b=t3.c OR t4.e>5 ...) AND ...
4488 Given the tables are accessed in the order t1->t2->t3->t4 for
4489 the selected query execution plan the lower level multiple
4490 equality =(t1.a,t2.b,t3.c,t4.d) formally should be converted to
4491 t1.a=t2.b AND t1.a=t3.c AND t1.a=t4.d. But t1.a=t2.a will be
4492 generated for the upper level. Also t3.c=t4.d will be generated there.
4493 So only t1.a=t3.c should be left in the lower level.
4494 If cond is equal to 0, then not more then one equality is generated
4495 and a pointer to it is returned as the result of the function.
4496
4497 @return
4498 - The condition with generated simple equalities or
4499 a pointer to the simple generated equality, if success.
4500 - 0, otherwise.
4501 */
4502
4503 5481119 static Item *eliminate_item_equal(THD *thd, Item *cond,
4504 COND_EQUAL *upper_levels,
4505 Item_equal *item_equal) {
4506 5481119 List<Item> eq_list;
4507 5481185 Item *eq_item = nullptr;
4508
7/10
✓ Branch 0 taken 5481213 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1702 times.
✓ Branch 3 taken 5479511 times.
✓ Branch 4 taken 1702 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1702 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1702 times.
✓ Branch 9 taken 5479511 times.
5481185 if (((Item *)item_equal)->const_item() && !item_equal->val_int())
4509
1/2
✓ Branch 0 taken 1702 times.
✗ Branch 1 not taken.
3404 return new Item_func_false();
4510 5479511 Item *const item_const = item_equal->get_const();
4511
1/2
✓ Branch 0 taken 5479428 times.
✗ Branch 1 not taken.
5479501 auto it = item_equal->get_fields().begin();
4512
2/2
✓ Branch 0 taken 1908851 times.
✓ Branch 1 taken 3570577 times.
5479428 if (!item_const) {
4513 /*
4514 If there is a const item, match all field items with the const item,
4515 otherwise match the second and subsequent field items with the first one:
4516 */
4517 1908851 it++;
4518 }
4519
4/6
✓ Branch 0 taken 10998059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10998036 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5518515 times.
✓ Branch 5 taken 5479521 times.
10998035 while (it != item_equal->get_fields().end()) {
4520 /*
4521 Generate an equality of the form:
4522 item_field = some previous field in item_equal's list.
4523
4524 First see if we really need to generate it:
4525 */
4526 5518515 Item_field *item_field = &*it++; // Field to generate equality for.
4527
1/2
✓ Branch 0 taken 5518451 times.
✗ Branch 1 not taken.
5518490 Item_equal *const upper = item_field->find_item_equal(upper_levels);
4528
2/2
✓ Branch 0 taken 114435 times.
✓ Branch 1 taken 5404016 times.
5518451 if (upper) // item_field is in this upper equality
4529 {
4530
6/6
✓ Branch 0 taken 113907 times.
✓ Branch 1 taken 528 times.
✓ Branch 2 taken 113708 times.
✓ Branch 3 taken 201 times.
✓ Branch 4 taken 113710 times.
✓ Branch 5 taken 727 times.
114435 if (item_const && upper->get_const())
4531 113710 continue; // Const at both levels, no need to generate at current level
4532 /*
4533 If the upper-level multiple equality contains this item, there is no
4534 need to generate the equality, unless item_field belongs to a
4535 semi-join nest that is used for Materialization, and refers to tables
4536 that are outside of the materialized semi-join nest,
4537 As noted in Item_equal::get_subst_item(), subquery materialization
4538 does not have this problem.
4539 */
4540 727 JOIN_TAB *const tab = item_field->field->table->reginfo.join_tab;
4541
4542
6/8
✓ Branch 0 taken 733 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 733 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 730 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 724 times.
✓ Branch 7 taken 3 times.
727 if (!(tab && sj_is_materialize_strategy(tab->get_sj_strategy()))) {
4543 Item_field *item_match;
4544
1/2
✓ Branch 0 taken 724 times.
✗ Branch 1 not taken.
724 auto li = item_equal->get_fields().begin();
4545
2/2
✓ Branch 0 taken 623 times.
✓ Branch 1 taken 101 times.
724 while ((item_match = &*li++) != item_field) {
4546
2/4
✓ Branch 0 taken 623 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 623 times.
✗ Branch 3 not taken.
623 if (item_match->find_item_equal(upper_levels) == upper)
4547 623 break; // (item_match, item_field) is also in upper level equality
4548 }
4549
2/2
✓ Branch 0 taken 623 times.
✓ Branch 1 taken 101 times.
724 if (item_match != item_field) continue;
4550 }
4551 } // ... if (upper).
4552
4553 /*
4554 item_field should be compared with the head of the multiple equality
4555 list.
4556 item_field may refer to a table that is within a semijoin materialization
4557 nest. In that case, the order of the join_tab entries may look like:
4558
4559 ot1 ot2 <subquery> ot5 SJM(it3 it4)
4560
4561 If we have a multiple equality
4562
4563 (ot1.c1, ot2.c2, <subquery>.c it3.c3, it4.c4, ot5.c5),
4564
4565 we should generate the following equalities:
4566 1. ot1.c1 = ot2.c2
4567 2. ot1.c1 = <subquery>.c
4568 3. it3.c3 = it4.c4
4569 4. ot1.c1 = ot5.c5
4570
4571 Equalities 1) and 4) are regular equalities between two outer tables.
4572 Equality 2) is an equality that matches the outer query with a
4573 materialized temporary table. It is either performed as a lookup
4574 into the materialized table (SJM-lookup), or as a condition on the
4575 outer table (SJM-scan).
4576 Equality 3) is evaluated during semijoin materialization.
4577
4578 If there is a const item, match against this one.
4579 Otherwise, match against the first field item in the multiple equality,
4580 unless the item is within a materialized semijoin nest, in case it will
4581 be matched against the first item within the SJM nest.
4582 @see JOIN::set_prefix_tables()
4583 @see Item_equal::get_subst_item()
4584 */
4585
4586 Item *const head =
4587
3/4
✓ Branch 0 taken 1931004 times.
✓ Branch 1 taken 3473116 times.
✓ Branch 2 taken 1931002 times.
✗ Branch 3 not taken.
5404120 item_const ? item_const : item_equal->get_subst_item(item_field);
4588
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 5403942 times.
5404118 if (head == item_field) continue;
4589
4590 // we have a pair, can generate 'item_field=head'
4591
3/4
✓ Branch 0 taken 23184 times.
✓ Branch 1 taken 5380758 times.
✓ Branch 2 taken 23184 times.
✗ Branch 3 not taken.
5403942 if (eq_item) eq_list.push_back(eq_item);
4592
4593
3/4
✓ Branch 0 taken 5403955 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1931145 times.
✓ Branch 3 taken 3472810 times.
5403942 if (head->type() == Item::FIELD_ITEM) {
4594 // Store away all fields that were considered equal, so that we are able
4595 // to undo this operation later if we have to. See
4596 // Item_func::ensure_multi_equality_fields_are_available for more details.
4597 1931145 Item_field *head_field = down_cast<Item_field *>(head);
4598 1931143 head_field->set_item_equal_all_join_nests(item_equal);
4599 }
4600
2/4
✓ Branch 0 taken 5404029 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5404021 times.
✗ Branch 3 not taken.
5403947 eq_item = new Item_func_eq(item_field, head);
4601
4602
6/8
✓ Branch 0 taken 5404031 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5404039 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 5404028 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 5404028 times.
5404021 if (!eq_item || down_cast<Item_func_eq *>(eq_item)->set_cmp_func())
4603 1 return nullptr;
4604
4605 5404028 eq_item->quick_fix_field();
4606
2/2
✓ Branch 0 taken 3473132 times.
✓ Branch 1 taken 1930845 times.
5403977 if (item_const != nullptr) {
4607
1/2
✓ Branch 0 taken 3473155 times.
✗ Branch 1 not taken.
3473132 eq_item->apply_is_true();
4608 Item::cond_result res;
4609
2/4
✓ Branch 0 taken 3473249 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3473249 times.
3473155 if (fold_condition(thd, eq_item, &eq_item, &res)) return nullptr;
4610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3473249 times.
3473249 if (res == Item::COND_FALSE) {
4611 eq_item = new (thd->mem_root) Item_func_false();
4612 if (eq_item == nullptr) return nullptr;
4613 return eq_item; // entire AND is false
4614
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3473249 times.
3473249 } else if (res == Item::COND_TRUE) {
4615 eq_item = new (thd->mem_root) Item_func_true();
4616 if (eq_item == nullptr) return nullptr;
4617 }
4618 }
4619 } // ... while ((item_field= it++))
4620
4621
6/6
✓ Branch 0 taken 893503 times.
✓ Branch 1 taken 4586018 times.
✓ Branch 2 taken 891696 times.
✓ Branch 3 taken 1795 times.
✓ Branch 4 taken 891700 times.
✓ Branch 5 taken 4587809 times.
5479521 if (!cond && !eq_list.head()) {
4622
3/4
✓ Branch 0 taken 65441 times.
✓ Branch 1 taken 826259 times.
✓ Branch 2 taken 65441 times.
✗ Branch 3 not taken.
957141 if (!eq_item) return new Item_func_true();
4623 826259 return eq_item;
4624 }
4625
4626
3/4
✓ Branch 0 taken 4554627 times.
✓ Branch 1 taken 33182 times.
✓ Branch 2 taken 4554627 times.
✗ Branch 3 not taken.
4587809 if (eq_item) eq_list.push_back(eq_item);
4627
2/2
✓ Branch 0 taken 1798 times.
✓ Branch 1 taken 4586011 times.
4587809 if (!cond)
4628
2/4
✓ Branch 0 taken 1798 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1798 times.
✗ Branch 3 not taken.
1798 cond = new Item_cond_and(eq_list);
4629 else {
4630
2/4
✓ Branch 0 taken 4586010 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4586010 times.
4586011 assert(cond->type() == Item::COND_ITEM);
4631
3/4
✓ Branch 0 taken 4552820 times.
✓ Branch 1 taken 33190 times.
✓ Branch 2 taken 4552825 times.
✗ Branch 3 not taken.
4586010 if (eq_list.elements) ((Item_cond *)cond)->add_at_head(&eq_list);
4632 }
4633
4634 4587813 cond->quick_fix_field();
4635
1/2
✓ Branch 0 taken 4587816 times.
✗ Branch 1 not taken.
4587812 cond->update_used_tables();
4636
4637 4587816 return cond;
4638 }
4639
4640 /**
4641 Substitute every field reference in a condition by the best equal field
4642 and eliminate all multiple equality predicates.
4643
4644 The function retrieves the cond condition and for each encountered
4645 multiple equality predicate it sorts the field references in it
4646 according to the order of tables specified by the table_join_idx
4647 parameter. Then it eliminates the multiple equality predicate by
4648 replacing it with the conjunction of simple equality predicates
4649 equating every field from the multiple equality to the first
4650 field in it, or to the constant, if there is any.
4651 After this, the function retrieves all other conjuncted
4652 predicates and substitutes every field reference by the field reference
4653 to the first equal field or equal constant if there are any.
4654
4655 @param thd the session context
4656 @param cond condition to process
4657 @param cond_equal multiple equalities to take into consideration
4658 @param table_join_idx index to tables determining field preference
4659
4660 @note
4661 At the first glance, a full sort of fields in multiple equality
4662 seems to be an overkill. Yet it's not the case due to possible
4663 new fields in multiple equality item of lower levels. We want
4664 the order in them to comply with the order of upper levels.
4665
4666 @return
4667 The transformed condition, or NULL in case of error
4668 */
4669
4670 4652902 Item *substitute_for_best_equal_field(THD *thd, Item *cond,
4671 COND_EQUAL *cond_equal,
4672 JOIN_TAB **table_join_idx) {
4673
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4652977 times.
4652902 assert(cond->is_bool_func());
4674
2/2
✓ Branch 0 taken 1939534 times.
✓ Branch 1 taken 2713447 times.
4652977 if (cond->type() == Item::COND_ITEM) {
4675 1939534 List<Item> *cond_list = ((Item_cond *)cond)->argument_list();
4676
4677 bool and_level =
4678
1/2
✓ Branch 0 taken 1939530 times.
✗ Branch 1 not taken.
1939534 ((Item_cond *)cond)->functype() == Item_func::COND_AND_FUNC;
4679
2/2
✓ Branch 0 taken 1919232 times.
✓ Branch 1 taken 20298 times.
1939530 if (and_level) {
4680 1919232 cond_equal = &((Item_cond_and *)cond)->cond_equal;
4681 1919232 cond_list->disjoin((List<Item> *)&cond_equal->current_level);
4682
4683
1/2
✓ Branch 0 taken 1919233 times.
✗ Branch 1 not taken.
1919231 List_iterator_fast<Item_equal> it(cond_equal->current_level);
4684 1737949 auto cmp = [table_join_idx](Item_field *f1, Item_field *f2) {
4685 1737949 return compare_fields_by_table_order(f1, f2, table_join_idx);
4686 1919233 };
4687 Item_equal *item_equal;
4688
2/2
✓ Branch 0 taken 4587599 times.
✓ Branch 1 taken 1919237 times.
6506824 while ((item_equal = it++)) {
4689
1/2
✓ Branch 0 taken 4587591 times.
✗ Branch 1 not taken.
4587599 item_equal->sort(cmp);
4690 }
4691 }
4692
4693
1/2
✓ Branch 0 taken 1939533 times.
✗ Branch 1 not taken.
1939535 List_iterator<Item> li(*cond_list);
4694 Item *item;
4695
2/2
✓ Branch 0 taken 2511113 times.
✓ Branch 1 taken 1939535 times.
4450647 while ((item = li++)) {
4696
1/2
✓ Branch 0 taken 2511114 times.
✗ Branch 1 not taken.
2511113 Item *new_item = substitute_for_best_equal_field(thd, item, cond_equal,
4697 table_join_idx);
4698
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2511114 times.
2511114 if (new_item == nullptr) return nullptr;
4699 /*
4700 This works OK with PS/SP re-execution as changes are made to
4701 the arguments of AND/OR items only
4702 */
4703
2/2
✓ Branch 0 taken 10534 times.
✓ Branch 1 taken 2500580 times.
2511114 if (new_item != item) li.replace(new_item);
4704 }
4705
4706
2/2
✓ Branch 0 taken 1919236 times.
✓ Branch 1 taken 20299 times.
1939535 if (and_level) {
4707
1/2
✓ Branch 0 taken 1919235 times.
✗ Branch 1 not taken.
1919236 List_iterator_fast<Item_equal> it(cond_equal->current_level);
4708 Item_equal *item_equal;
4709
2/2
✓ Branch 0 taken 4587550 times.
✓ Branch 1 taken 1917699 times.
6505253 while ((item_equal = it++)) {
4710
1/2
✓ Branch 0 taken 4587556 times.
✗ Branch 1 not taken.
4587550 cond = eliminate_item_equal(thd, cond, cond_equal->upper_levels,
4711 item_equal);
4712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4587556 times.
4587556 if (cond == nullptr) return nullptr;
4713 // This occurs when eliminate_item_equal() founds that cond is
4714 // always false and substitutes it with a false value.
4715 // Due to this, value of item_equal will be 0, so just return it.
4716
3/4
✓ Branch 0 taken 4587556 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1538 times.
✓ Branch 3 taken 4586018 times.
4587556 if (cond->type() != Item::COND_ITEM) break;
4717 }
4718 }
4719
5/6
✓ Branch 0 taken 1939539 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1938001 times.
✓ Branch 3 taken 1538 times.
✓ Branch 4 taken 13972 times.
✓ Branch 5 taken 1925567 times.
3877537 if (cond->type() == Item::COND_ITEM &&
4720
2/2
✓ Branch 0 taken 13972 times.
✓ Branch 1 taken 1924029 times.
1938001 !((Item_cond *)cond)->argument_list()->elements)
4721
3/6
✓ Branch 0 taken 13972 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13972 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13972 times.
✗ Branch 5 not taken.
27944 cond = cond->val_bool() ? implicit_cast<Item *>(new Item_func_true())
4722 : implicit_cast<Item *>(new Item_func_false());
4723
4/4
✓ Branch 0 taken 2713338 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 893646 times.
✓ Branch 3 taken 1819799 times.
5426865 } else if (cond->type() == Item::FUNC_ITEM &&
4724
2/2
✓ Branch 0 taken 893647 times.
✓ Branch 1 taken 1819771 times.
2713338 (down_cast<Item_func *>(cond))->functype() ==
4725 Item_func::MULT_EQUAL_FUNC) {
4726 893646 Item_equal *item_equal = down_cast<Item_equal *>(cond);
4727 893657 item_equal->sort([table_join_idx](Item_field *f1, Item_field *f2) {
4728 734538 return compare_fields_by_table_order(f1, f2, table_join_idx);
4729 });
4730
6/6
✓ Branch 0 taken 888012 times.
✓ Branch 1 taken 5581 times.
✓ Branch 2 taken 882340 times.
✓ Branch 3 taken 5725 times.
✓ Branch 4 taken 882298 times.
✓ Branch 5 taken 11348 times.
893593 if (cond_equal && cond_equal->current_level.head() == item_equal)
4731 882298 cond_equal = cond_equal->upper_levels;
4732 893646 return eliminate_item_equal(thd, nullptr, cond_equal, item_equal);
4733 } else {
4734 1819799 uchar *dummy = nullptr;
4735
1/2
✓ Branch 0 taken 1819796 times.
✗ Branch 1 not taken.
1819799 if (cond->compile(&Item::visit_all_analyzer, &dummy,
4736
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1819796 times.
1819796 &Item::replace_equal_field, nullptr) == nullptr)
4737 return nullptr;
4738 }
4739 3759335 return cond;
4740 }
4741
4742 /**
4743 change field = field to field = const for each found field = const in the
4744 and_level
4745
4746 @param thd Thread handler
4747 @param save_list saved list of COND_CMP
4748 @param and_father father of AND op
4749 @param cond Condition where fields are replaced with constant values
4750 @param field The field that will be substituted
4751 @param value The substitution value
4752
4753 @returns false if success, true if error
4754 */
4755
4756 549863 static bool change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
4757 Item *and_father, Item *cond, Item *field,
4758 Item *value) {
4759
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 549863 times.
549863 assert(cond->real_item()->is_bool_func());
4760
2/2
✓ Branch 0 taken 151165 times.
✓ Branch 1 taken 398698 times.
549863 if (cond->type() == Item::COND_ITEM) {
4761 151165 Item_cond *const item_cond = down_cast<Item_cond *>(cond);
4762
1/2
✓ Branch 0 taken 151165 times.
✗ Branch 1 not taken.
151165 bool and_level = item_cond->functype() == Item_func::COND_AND_FUNC;
4763
1/2
✓ Branch 0 taken 151165 times.
✗ Branch 1 not taken.
151165 List_iterator<Item> li(*item_cond->argument_list());
4764 Item *item;
4765
2/2
✓ Branch 0 taken 399107 times.
✓ Branch 1 taken 151165 times.
550272 while ((item = li++)) {
4766
4/6
✓ Branch 0 taken 398302 times.
✓ Branch 1 taken 805 times.
✓ Branch 2 taken 399107 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 399107 times.
399107 if (change_cond_ref_to_const(thd, save_list, and_level ? cond : item,
4767 item, field, value))
4768 return true;
4769 }
4770 151165 return false;
4771 }
4772
2/2
✓ Branch 0 taken 141160 times.
✓ Branch 1 taken 257538 times.
398698 if (cond->eq_cmp_result() == Item::COND_OK)
4773 141160 return false; // Not a boolean function
4774
4775 257538 Item_bool_func2 *func = down_cast<Item_bool_func2 *>(cond);
4776 257538 Item **args = func->arguments();
4777 257538 Item *left_item = args[0];
4778 257538 Item *right_item = args[1];
4779 257538 Item_func::Functype functype = func->functype();
4780
4781
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 88 times.
257649 if (right_item->eq(field, false) && left_item != value &&
4782
5/6
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 257427 times.
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 23 times.
✓ Branch 5 taken 257515 times.
257672 right_item->cmp_context == field->cmp_context &&
4783
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 8 times.
23 (left_item->result_type() != STRING_RESULT ||
4784
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 value->result_type() != STRING_RESULT ||
4785
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 left_item->collation.collation == value->collation.collation)) {
4786 23 Item *const clone = value->clone_item();
4787
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (thd->is_error()) return true;
4788
4789
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 21 times.
23 if (clone == nullptr) return false;
4790
4791 21 clone->collation.set(right_item->collation);
4792 21 thd->change_item_tree(args + 1, clone);
4793 21 func->update_used_tables();
4794
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
21 if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
4795
5/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 10 times.
42 and_father != cond && !left_item->const_item()) {
4796 11 cond->marker = Item::MARKER_CONST_PROPAG;
4797
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 COND_CMP *const cond_cmp = new COND_CMP(and_father, func);
4798
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (cond_cmp == nullptr) return true;
4799
4800 11 save_list->push_back(cond_cmp);
4801 }
4802
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (func->set_cmp_func()) return true;
4803
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 150652 times.
408207 } else if (left_item->eq(field, false) && right_item != value &&
4804
5/6
✓ Branch 0 taken 150692 times.
✓ Branch 1 taken 106823 times.
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 37 times.
✓ Branch 5 taken 257478 times.
408247 left_item->cmp_context == field->cmp_context &&
4805
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 9 times.
40 (right_item->result_type() != STRING_RESULT ||
4806
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 value->result_type() != STRING_RESULT ||
4807
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 3 times.
31 right_item->collation.collation == value->collation.collation)) {
4808 37 Item *const clone = value->clone_item();
4809
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 if (thd->is_error()) return true;
4810
4811
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 if (clone == nullptr) return false;
4812
4813 37 clone->collation.set(left_item->collation);
4814 37 thd->change_item_tree(args, clone);
4815 37 value = clone;
4816 37 func->update_used_tables();
4817
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
37 if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
4818
6/6
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 24 times.
74 and_father != cond && !right_item->const_item()) {
4819 13 args[0] = args[1]; // For easy check
4820 13 thd->change_item_tree(args + 1, value);
4821 13 cond->marker = Item::MARKER_CONST_PROPAG;
4822
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 COND_CMP *const cond_cmp = new COND_CMP(and_father, func);
4823
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (cond_cmp == nullptr) return true;
4824
4825 13 save_list->push_back(cond_cmp);
4826 }
4827
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 if (func->set_cmp_func()) return true;
4828 }
4829 257536 return false;
4830 }
4831
4832 /**
4833 Propagate constant values in a condition
4834
4835 @param thd Thread handler
4836 @param save_list saved list of COND_CMP
4837 @param and_father father of AND op
4838 @param cond Condition for which constant values are propagated
4839
4840 @returns false if success, true if error
4841 */
4842 8674258 static bool propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
4843 Item *and_father, Item *cond) {
4844
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8674271 times.
8674258 assert(cond->real_item()->is_bool_func());
4845
2/2
✓ Branch 0 taken 1846467 times.
✓ Branch 1 taken 6827831 times.
8674271 if (cond->type() == Item::COND_ITEM) {
4846 1846467 Item_cond *const item_cond = down_cast<Item_cond *>(cond);
4847
1/2
✓ Branch 0 taken 1846409 times.
✗ Branch 1 not taken.
1846411 bool and_level = item_cond->functype() == Item_func::COND_AND_FUNC;
4848
1/2
✓ Branch 0 taken 1846411 times.
✗ Branch 1 not taken.
1846409 List_iterator_fast<Item> li(*item_cond->argument_list());
4849 Item *item;
4850
1/2
✓ Branch 0 taken 1846405 times.
✗ Branch 1 not taken.
1846411 I_List<COND_CMP> save;
4851
2/2
✓ Branch 0 taken 6908816 times.
✓ Branch 1 taken 1846409 times.
8755223 while ((item = li++)) {
4852
5/6
✓ Branch 0 taken 5889289 times.
✓ Branch 1 taken 1019527 times.
✓ Branch 2 taken 6908819 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 6908818 times.
6908816 if (propagate_cond_constants(thd, &save, and_level ? cond : item, item))
4853 1 return true;
4854 }
4855
2/2
✓ Branch 0 taken 1816763 times.
✓ Branch 1 taken 29646 times.
1846409 if (and_level) { // Handle other found items
4856
1/2
✓ Branch 0 taken 1816763 times.
✗ Branch 1 not taken.
1816763 I_List_iterator<COND_CMP> cond_itr(save);
4857 COND_CMP *cond_cmp;
4858
3/4
✓ Branch 0 taken 1816785 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 1816761 times.
1816787 while ((cond_cmp = cond_itr++)) {
4859
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 Item **args = cond_cmp->cmp_func->arguments();
4860
3/6
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 24 times.
48 if (!args[0]->const_item() &&
4861
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 change_cond_ref_to_const(thd, &save, cond_cmp->and_level,
4862
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 cond_cmp->and_level, args[0], args[1]))
4863 return true;
4864 }
4865 }
4866
2/2
✓ Branch 0 taken 5883786 times.
✓ Branch 1 taken 944045 times.
6827831 } else if (and_father != cond &&
4867
2/2
✓ Branch 0 taken 5883779 times.
✓ Branch 1 taken 7 times.
5883786 cond->marker != Item::MARKER_CONST_PROPAG) // In a AND group
4868 {
4869 Item_func *func;
4870
1/2
✓ Branch 0 taken 5883728 times.
✗ Branch 1 not taken.
11767506 if (cond->type() == Item::FUNC_ITEM &&
4871
4/4
✓ Branch 0 taken 5883727 times.
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 175749 times.
✓ Branch 3 taken 5708033 times.
11767509 (func = down_cast<Item_func *>(cond)) &&
4872
2/2
✓ Branch 0 taken 5708105 times.
✓ Branch 1 taken 175619 times.
5883728 (func->functype() == Item_func::EQ_FUNC ||
4873
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 5707984 times.
5708105 func->functype() == Item_func::EQUAL_FUNC)) {
4874 175749 Item **args = func->arguments();
4875 175749 bool left_const = args[0]->const_item();
4876 175749 bool right_const = args[1]->const_item();
4877
6/6
✓ Branch 0 taken 199 times.
✓ Branch 1 taken 175550 times.
✓ Branch 2 taken 97 times.
✓ Branch 3 taken 102 times.
✓ Branch 4 taken 171045 times.
✓ Branch 5 taken 4704 times.
351396 if (!(left_const && right_const) &&
4878
2/2
✓ Branch 0 taken 171045 times.
✓ Branch 1 taken 4602 times.
175647 args[0]->result_type() == args[1]->result_type()) {
4879
2/2
✓ Branch 0 taken 150639 times.
✓ Branch 1 taken 20406 times.
171045 if (right_const) {
4880 150639 Item *item = args[1];
4881
3/4
✓ Branch 0 taken 150639 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 150638 times.
150639 if (resolve_const_item(thd, &item, args[0])) return true;
4882
1/2
✓ Branch 0 taken 150638 times.
✗ Branch 1 not taken.
150638 thd->change_item_tree(&args[1], item);
4883
1/2
✓ Branch 0 taken 150638 times.
✗ Branch 1 not taken.
150638 func->update_used_tables();
4884
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 150638 times.
150638 if (change_cond_ref_to_const(thd, save_list, and_father, and_father,
4885
1/2
✓ Branch 0 taken 150638 times.
✗ Branch 1 not taken.
150638 args[0], args[1]))
4886 return true;
4887
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 20312 times.
20406 } else if (left_const) {
4888 94 Item *item = args[0];
4889
2/4
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 94 times.
94 if (resolve_const_item(thd, &item, args[1])) return true;
4890
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 thd->change_item_tree(&args[0], item);
4891
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 func->update_used_tables();
4892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
94 if (change_cond_ref_to_const(thd, save_list, and_father, and_father,
4893
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 args[1], args[0]))
4894 return true;
4895 }
4896 }
4897 }
4898 }
4899
4900 8674240 return false;
4901 }
4902
4903 /**
4904 Assign each nested join structure a bit in nested_join_map.
4905
4906 @param join_list List of tables
4907 @param first_unused Number of first unused bit in nested_join_map before the
4908 call
4909
4910 @note
4911 This function is called after simplify_joins(), when there are no
4912 redundant nested joins.
4913 We cannot have more nested joins in a query block than there are tables,
4914 so as long as the number of bits in nested_join_map is not less than the
4915 maximum number of tables in a query block, nested_join_map can never
4916 overflow.
4917
4918 @return
4919 First unused bit in nested_join_map after the call.
4920 */
4921
4922 19043662 uint build_bitmap_for_nested_joins(mem_root_deque<TABLE_LIST *> *join_list,
4923 uint first_unused) {
4924
1/2
✓ Branch 0 taken 19044655 times.
✗ Branch 1 not taken.
19043662 DBUG_TRACE;
4925
7/12
✓ Branch 0 taken 19044678 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19044847 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3984829 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3984831 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 23028939 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3984824 times.
✓ Branch 11 taken 19044115 times.
23029484 for (TABLE_LIST *table : *join_list) {
4926 NESTED_JOIN *nested_join;
4927
2/2
✓ Branch 0 taken 6262 times.
✓ Branch 1 taken 3978567 times.
3984829 if ((nested_join = table->nested_join)) {
4928 // We should have a join condition or a semi-join condition or both
4929
3/4
✓ Branch 0 taken 4433 times.
✓ Branch 1 taken 1829 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4433 times.
6262 assert((table->join_cond() != nullptr) || table->is_sj_nest());
4930
4931 6262 nested_join->nj_map = 0;
4932 6262 nested_join->nj_total = 0;
4933 /*
4934 We only record nested join information for outer join nests.
4935 Tables belonging in semi-join nests are recorded in the
4936 embedding outer join nest, if one exists.
4937 */
4938
2/2
✓ Branch 0 taken 1829 times.
✓ Branch 1 taken 4433 times.
6262 if (table->join_cond()) {
4939
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1829 times.
1829 assert(first_unused < sizeof(nested_join_map) * 8);
4940 1829 nested_join->nj_map = (nested_join_map)1 << first_unused++;
4941 1829 nested_join->nj_total = nested_join->join_list.size();
4942
1/2
✓ Branch 0 taken 4433 times.
✗ Branch 1 not taken.
4433 } else if (table->is_sj_nest()) {
4943 4433 NESTED_JOIN *const outer_nest =
4944
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 4408 times.
4433 table->embedding ? table->embedding->nested_join : nullptr;
4945 /*
4946 The semi-join nest has already been counted into the table count
4947 for the outer join nest as one table, so subtract 1 from the
4948 table count.
4949 */
4950
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 4408 times.
4433 if (outer_nest)
4951 25 outer_nest->nj_total += (nested_join->join_list.size() - 1);
4952 } else
4953 assert(false);
4954
4955 first_unused =
4956
1/2
✓ Branch 0 taken 6262 times.
✗ Branch 1 not taken.
6262 build_bitmap_for_nested_joins(&nested_join->join_list, first_unused);
4957 }
4958 }
4959 19044744 return first_unused;
4960 19044115 }
4961
4962 /** Update the dependency map for the tables. */
4963
4964 1903441 void JOIN::update_depend_map() {
4965
3/6
✓ Branch 0 taken 1903442 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1903444 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1903452 times.
✗ Branch 5 not taken.
1903441 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
4966
2/2
✓ Branch 0 taken 6477201 times.
✓ Branch 1 taken 1903469 times.
8380670 for (uint tableno = 0; tableno < tables; tableno++) {
4967 6477201 JOIN_TAB *const tab = best_ref[tableno];
4968 6477201 TABLE_REF *const ref = &tab->ref();
4969 6477217 table_map depend_map = 0;
4970 6477217 Item **item = ref->items;
4971
2/2
✓ Branch 0 taken 2743437 times.
✓ Branch 1 taken 6477219 times.
9220656 for (uint i = 0; i < ref->key_parts; i++, item++)
4972 2743437 depend_map |= (*item)->used_tables();
4973 6477219 depend_map &= ~PSEUDO_TABLE_BITS;
4974 6477219 ref->depend_map = depend_map;
4975
2/2
✓ Branch 0 taken 3871789 times.
✓ Branch 1 taken 6477219 times.
10349008 for (JOIN_TAB **tab2 = map2table; depend_map; tab2++, depend_map >>= 1) {
4976
2/2
✓ Branch 0 taken 1812553 times.
✓ Branch 1 taken 2059236 times.
3871789 if (depend_map & 1) ref->depend_map |= (*tab2)->ref().depend_map;
4977 }
4978 }
4979 1903469 }
4980
4981 /** Update the dependency map for the sort order. */
4982
4983 3627771 void JOIN::update_depend_map(ORDER *order) {
4984
1/2
✓ Branch 0 taken 3627791 times.
✗ Branch 1 not taken.
3627771 DBUG_TRACE;
4985
2/2
✓ Branch 0 taken 1023214 times.
✓ Branch 1 taken 3627793 times.
4651007 for (; order; order = order->next) {
4986 table_map depend_map;
4987
1/2
✓ Branch 0 taken 1023214 times.
✗ Branch 1 not taken.
1023214 order->item[0]->update_used_tables();
4988 1023216 order->depend_map = depend_map =
4989
1/2
✓ Branch 0 taken 1023216 times.
✗ Branch 1 not taken.
1023214 order->item[0]->used_tables() & ~INNER_TABLE_BIT;
4990 1023216 order->used = 0;
4991 // Not item_sum(), RAND() and no reference to table outside of sub select
4992
4/4
✓ Branch 0 taken 1021838 times.
✓ Branch 1 taken 1378 times.
✓ Branch 2 taken 1021524 times.
✓ Branch 3 taken 1692 times.
2045054 if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT)) &&
4993
2/2
✓ Branch 0 taken 1021524 times.
✓ Branch 1 taken 314 times.
1021838 !order->item[0]->has_aggregation()) {
4994
2/2
✓ Branch 0 taken 1343055 times.
✓ Branch 1 taken 1021524 times.
2364579 for (JOIN_TAB **tab = map2table; depend_map; tab++, depend_map >>= 1) {
4995
2/2
✓ Branch 0 taken 1079315 times.
✓ Branch 1 taken 263740 times.
1343055 if (depend_map & 1) order->depend_map |= (*tab)->ref().depend_map;
4996 }
4997 }
4998 }
4999 3627793 }
5000
5001 /**
5002 Update equalities and keyuse references after semi-join materialization
5003 strategy is chosen.
5004
5005 @details
5006 For each multiple equality that contains a field that is selected
5007 from a subquery, and that subquery is executed using a semi-join
5008 materialization strategy, add the corresponding column in the materialized
5009 temporary table to the equality.
5010 For each injected semi-join equality that is not converted to
5011 multiple equality, replace the reference to the expression selected
5012 from the subquery with the corresponding column in the temporary table.
5013
5014 This is needed to properly reflect the equalities that involve injected
5015 semi-join equalities when materialization strategy is chosen.
5016 @see eliminate_item_equal() for how these equalities are used to generate
5017 correct equality predicates.
5018
5019 The MaterializeScan semi-join strategy requires some additional processing:
5020 All primary tables after the materialized temporary table must be inspected
5021 for keyuse objects that point to expressions from the subquery tables.
5022 These references must be replaced with references to corresponding columns
5023 in the materialized temporary table instead. Those primary tables using
5024 ref access will thus be made to depend on the materialized temporary table
5025 instead of the subquery tables.
5026
5027 Only the injected semi-join equalities need this treatment, other predicates
5028 will be handled correctly by the regular item substitution process.
5029
5030 @return False if success, true if error
5031 */
5032
5033 2721 bool JOIN::update_equalities_for_sjm() {
5034
3/6
✓ Branch 0 taken 2721 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2721 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2721 times.
✗ Branch 5 not taken.
2721 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
5035
1/2
✓ Branch 0 taken 2721 times.
✗ Branch 1 not taken.
2721 List_iterator<Semijoin_mat_exec> sj_it(sjm_exec_list);
5036 Semijoin_mat_exec *sjm_exec;
5037
2/2
✓ Branch 0 taken 934 times.
✓ Branch 1 taken 2721 times.
3655 while ((sjm_exec = sj_it++)) {
5038 934 TABLE_LIST *const sj_nest = sjm_exec->sj_nest;
5039
5040 Item *cond;
5041 /*
5042 Conditions involving SJ-inner tables are only to be found in the closest
5043 nest's condition, which may be an AJ nest, a LEFT JOIN nest, or the
5044 WHERE clause.
5045 */
5046
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 924 times.
934 if (sj_nest->is_aj_nest())
5047 10 cond = sj_nest->join_cond_optim();
5048
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 910 times.
924 else if (sj_nest->outer_join_nest())
5049 14 cond = sj_nest->outer_join_nest()->join_cond_optim();
5050 else
5051 910 cond = where_cond;
5052
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 933 times.
934 if (!cond) continue;
5053
5054 933 uchar *dummy = nullptr;
5055
1/2
✓ Branch 0 taken 933 times.
✗ Branch 1 not taken.
933 cond = cond->compile(&Item::equality_substitution_analyzer, &dummy,
5056 &Item::equality_substitution_transformer,
5057 (uchar *)sj_nest);
5058
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 933 times.
933 if (cond == nullptr) return true;
5059
5060
1/2
✓ Branch 0 taken 933 times.
✗ Branch 1 not taken.
933 cond->update_used_tables();
5061
5062 // Loop over all primary tables that follow the materialized table
5063
2/2
✓ Branch 0 taken 1137 times.
✓ Branch 1 taken 933 times.
2070 for (uint j = sjm_exec->mat_table_index + 1; j < primary_tables; j++) {
5064 1137 JOIN_TAB *const tab = best_ref[j];
5065 2247 for (Key_use *keyuse = tab->position()->key;
5066
6/6
✓ Branch 0 taken 2173 times.
✓ Branch 1 taken 74 times.
✓ Branch 2 taken 1114 times.
✓ Branch 3 taken 1059 times.
✓ Branch 4 taken 1110 times.
✓ Branch 5 taken 1137 times.
3361 keyuse && keyuse->table_ref == tab->table_ref &&
5067
2/2
✓ Branch 0 taken 1110 times.
✓ Branch 1 taken 4 times.
1114 keyuse->key == tab->position()->key->key;
5068 keyuse++) {
5069 1110 uint fieldno = 0;
5070
6/10
✓ Branch 0 taken 1110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1111 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1422 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1111 times.
✓ Branch 9 taken 311 times.
1422 for (Item *old : sj_nest->nested_join->sj_inner_exprs) {
5071
5/8
✓ Branch 0 taken 1111 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1111 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1111 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 799 times.
✓ Branch 7 taken 312 times.
1111 if (old->real_item()->eq(keyuse->val->real_item(), false)) {
5072 /*
5073 Replace the expression selected from the subquery with the
5074 corresponding column of the materialized temporary table.
5075 */
5076 799 keyuse->val = sj_nest->nested_join->sjm.mat_fields[fieldno];
5077
1/2
✓ Branch 0 taken 799 times.
✗ Branch 1 not taken.
799 keyuse->used_tables = keyuse->val->used_tables();
5078 799 break;
5079 }
5080
1/2
✓ Branch 0 taken 312 times.
✗ Branch 1 not taken.
312 fieldno++;
5081 }
5082 }
5083 }
5084 }
5085
5086 2721 return false;
5087 }
5088
5089 /**
5090 Assign set of available (prefix) tables to all tables in query block.
5091 Also set added tables, ie the tables added in each JOIN_TAB compared to the
5092 previous JOIN_TAB.
5093 This function must be called for every query block after the table order
5094 has been determined.
5095 */
5096
5097 1815620 void JOIN::set_prefix_tables() {
5098
3/6
✓ Branch 0 taken 1815623 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1815626 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1815637 times.
✗ Branch 5 not taken.
1815620 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
5099
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1815638 times.
1815634 assert(!plan_is_const());
5100 /*
5101 The const tables are available together with the first non-const table in
5102 the join order.
5103 */
5104 1815638 table_map const initial_tables_map =
5105
2/2
✓ Branch 0 taken 1815488 times.
✓ Branch 1 taken 150 times.
1815638 const_table_map | (allow_outer_refs ? OUTER_REF_TABLE_BIT : 0);
5106
5107 1815638 table_map current_tables_map = initial_tables_map;
5108 1815638 table_map prev_tables_map = (table_map)0;
5109 1815638 table_map saved_tables_map = (table_map)0;
5110
5111 1815638 JOIN_TAB *last_non_sjm_tab = nullptr; // Track the last non-sjm table
5112
5113
2/2
✓ Branch 0 taken 6295701 times.
✓ Branch 1 taken 1815646 times.
8111347 for (uint i = const_tables; i < tables; i++) {
5114 6295701 JOIN_TAB *const tab = best_ref[i];
5115
2/2
✓ Branch 0 taken 2467356 times.
✓ Branch 1 taken 3828360 times.
6295701 if (!tab->table()) continue;
5116 /*
5117 Tables that are within SJ-Materialization nests cannot have their
5118 conditions referring to preceding non-const tables.
5119 - If we're looking at the first SJM table, reset current_tables_map
5120 to refer to only allowed tables
5121 @see Item_equal::get_subst_item()
5122 @see eliminate_item_equal()
5123 */
5124
2/2
✓ Branch 0 taken 2374 times.
✓ Branch 1 taken 3825977 times.
3828360 if (sj_is_materialize_strategy(tab->get_sj_strategy())) {
5125 2374 const table_map sjm_inner_tables = tab->emb_sj_nest->sj_inner_tables;
5126
2/2
✓ Branch 0 taken 934 times.
✓ Branch 1 taken 1440 times.
2374 if (!(sjm_inner_tables & current_tables_map)) {
5127 934 saved_tables_map = current_tables_map;
5128 934 current_tables_map = initial_tables_map;
5129 934 prev_tables_map = (table_map)0;
5130 }
5131
5132 2374 current_tables_map |= tab->table_ref->map();
5133 2374 tab->set_prefix_tables(current_tables_map, prev_tables_map);
5134 2374 prev_tables_map = current_tables_map;
5135
5136
2/2
✓ Branch 0 taken 934 times.
✓ Branch 1 taken 1440 times.
2374 if (!(sjm_inner_tables & ~current_tables_map)) {
5137 /*
5138 At the end of a semi-join materialization nest,
5139 add non-deterministic expressions to the last table of the nest:
5140 */
5141 934 tab->add_prefix_tables(RAND_TABLE_BIT);
5142
5143 // Restore the previous map:
5144 934 current_tables_map = saved_tables_map;
5145 934 prev_tables_map =
5146
1/2
✓ Branch 0 taken 934 times.
✗ Branch 1 not taken.
934 last_non_sjm_tab ? last_non_sjm_tab->prefix_tables() : (table_map)0;
5147 }
5148 } else {
5149 3825977 last_non_sjm_tab = tab;
5150 3825977 current_tables_map |= tab->table_ref->map();
5151 3825979 tab->set_prefix_tables(current_tables_map, prev_tables_map);
5152 3825979 prev_tables_map = current_tables_map;
5153 }
5154 }
5155 /*
5156 Non-deterministic expressions must be added to the last table's condition.
5157 It solves problem with queries like SELECT * FROM t1 WHERE rand() > 0.5
5158 */
5159
2/2
✓ Branch 0 taken 1815642 times.
✓ Branch 1 taken 4 times.
1815646 if (last_non_sjm_tab != nullptr)
5160 1815642 last_non_sjm_tab->add_prefix_tables(RAND_TABLE_BIT);
5161 1815644 }
5162
5163 /**
5164 Calculate best possible join order and initialize the join structure.
5165
5166 @return true if success, false if error.
5167
5168 The JOIN object is populated with statistics about the query,
5169 and a plan with table order and access method selection is made.
5170
5171 The list of tables to be optimized is taken from query_block->leaf_tables.
5172 JOIN::where_cond is also used in the optimization.
5173 As a side-effect, JOIN::keyuse_array is populated with key_use information.
5174
5175 Here is an overview of the logic of this function:
5176
5177 - Initialize JOIN data structures and setup basic dependencies between tables.
5178
5179 - Update dependencies based on join information.
5180
5181 - Make key descriptions (update_ref_and_keys()).
5182
5183 - Pull out semi-join tables based on table dependencies.
5184
5185 - Extract tables with zero or one rows as const tables.
5186
5187 - Read contents of const tables, substitute columns from these tables with
5188 actual data. Also keep track of empty tables vs. one-row tables.
5189
5190 - After const table extraction based on row count, more tables may
5191 have become functionally dependent. Extract these as const tables.
5192
5193 - Add new sargable predicates based on retrieved const values.
5194
5195 - Calculate number of rows to be retrieved from each table.
5196
5197 - Calculate cost of potential semi-join materializations.
5198
5199 - Calculate best possible join order based on available statistics.
5200
5201 - Fill in remaining information for the generated join order.
5202 */
5203
5204 1912109 bool JOIN::make_join_plan() {
5205
1/2
✓ Branch 0 taken 1912125 times.
✗ Branch 1 not taken.
1912109 DBUG_TRACE;
5206
5207 1912125 SARGABLE_PARAM *sargables = nullptr;
5208
5209 1912125 Opt_trace_context *const trace = &thd->opt_trace;
5210
5211
3/4
✓ Branch 0 taken 1912120 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1912118 times.
1912125 if (init_planner_arrays()) // Create and initialize the arrays
5212 2 return true;
5213
5214 // Outer join dependencies were initialized above, now complete the analysis.
5215
6/6
✓ Branch 0 taken 1761434 times.
✓ Branch 1 taken 150684 times.
✓ Branch 2 taken 492 times.
✓ Branch 3 taken 1760943 times.
✓ Branch 4 taken 151177 times.
✓ Branch 5 taken 1760942 times.
1912118 if (query_block->outer_join || query_block->is_recursive()) {
5216
3/4
✓ Branch 0 taken 151175 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 151171 times.
151177 if (propagate_dependencies()) {
5217 /*
5218 Catch illegal join order.
5219 SQL2011 forbids:
5220 WITH RECURSIVE rec AS (
5221 ... UNION ALL SELECT ... FROM tbl LEFT JOIN rec ON...)c...
5222 MySQL also forbids the same query with STRAIGHT_JOIN instead of LEFT
5223 JOIN, because the algorithm of with-recursive imposes that "rec" be
5224 first in plan, i.e. "tbl" depends on "rec", but STRAIGHT_JOIN imposes
5225 the opposite dependency.
5226 */
5227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 assert(query_block->is_recursive());
5228 4 my_error(ER_CTE_RECURSIVE_FORBIDDEN_JOIN_ORDER, MYF(0),
5229
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 query_block->recursive_reference->alias);
5230 4 return true;
5231 }
5232 151171 init_key_dependencies();
5233 }
5234
5235
2/2
✓ Branch 0 taken 2702 times.
✓ Branch 1 taken 1909417 times.
1912115 if (unlikely(trace->is_started()))
5236
1/2
✓ Branch 0 taken 2702 times.
✗ Branch 1 not taken.
2702 trace_table_dependencies(trace, join_tab, primary_tables);
5237
5238 // Build the key access information, which is the basis for ref access.
5239
4/4
✓ Branch 0 taken 606911 times.
✓ Branch 1 taken 1305208 times.
✓ Branch 2 taken 4092 times.
✓ Branch 3 taken 602819 times.
1912119 if (where_cond || query_block->outer_join) {
5240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1309292 times.
1309292 if (update_ref_and_keys(thd, &keyuse_array, join_tab, tables, where_cond,
5241
1/2
✓ Branch 0 taken 1309292 times.
✗ Branch 1 not taken.
1309300 ~query_block->outer_join, query_block, &sargables))
5242 return true;
5243 }
5244
5245 /*
5246 Pull out semi-join tables based on dependencies. Dependencies are valid
5247 throughout the lifetime of a query, so this operation can be performed
5248 on the first optimization only.
5249 */
5250
6/8
✓ Branch 0 taken 1726616 times.
✓ Branch 1 taken 185495 times.
✓ Branch 2 taken 1726617 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4435 times.
✓ Branch 5 taken 1722182 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1912112 times.
1916546 if (!query_block->sj_pullout_done && !query_block->sj_nests.empty() &&
5251
2/4
✓ Branch 0 taken 4435 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4435 times.
4435 pull_out_semijoin_tables(this))
5252 return true;
5253
5254 1912112 query_block->sj_pullout_done = true;
5255 1912112 const uint sj_nests = query_block->sj_nests.size(); // Changed by pull-out
5256
5257
2/2
✓ Branch 0 taken 1908158 times.
✓ Branch 1 taken 3953 times.
1912107 if (!(query_block->active_options() & OPTION_NO_CONST_TABLES)) {
5258 // Detect tables that are const (0 or 1 row) and read their contents.
5259
2/4
✓ Branch 0 taken 1908167 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1908167 times.
1908158 if (extract_const_tables()) return true;
5260
5261 // Detect tables that are functionally dependent on const values.
5262
3/4
✓ Branch 0 taken 1908167 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 87 times.
✓ Branch 3 taken 1908080 times.
1908167 if (extract_func_dependent_tables()) return true;
5263 }
5264 // Possibly able to create more sargable predicates from const rows.
5265
5/6
✓ Branch 0 taken 98405 times.
✓ Branch 1 taken 1813628 times.
✓ Branch 2 taken 90395 times.
✓ Branch 3 taken 8010 times.
✓ Branch 4 taken 90396 times.
✗ Branch 5 not taken.
1912033 if (const_tables && sargables) update_sargable_from_const(sargables);
5266
5267 // Make a first estimate of the fanout for each table in the query block.
5268
2/4
✓ Branch 0 taken 1912030 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1912030 times.
1912034 if (estimate_rowcount()) return true;
5269
5270 /*
5271 Apply join order hints, with the exception of
5272 JOIN_FIXED_ORDER and STRAIGHT_JOIN.
5273 */
5274
4/4
✓ Branch 0 taken 11170 times.
✓ Branch 1 taken 1900860 times.
✓ Branch 2 taken 11165 times.
✓ Branch 3 taken 1900865 times.
1923200 if (query_block->opt_hints_qb &&
5275
2/2
✓ Branch 0 taken 11165 times.
✓ Branch 1 taken 5 times.
11170 !(query_block->active_options() & SELECT_STRAIGHT_JOIN))
5276
1/2
✓ Branch 0 taken 11165 times.
✗ Branch 1 not taken.
11165 query_block->opt_hints_qb->apply_join_order_hints(this);
5277
5278
2/2
✓ Branch 0 taken 2721 times.
✓ Branch 1 taken 1909309 times.
1912030 if (sj_nests) {
5279
1/2
✓ Branch 0 taken 2721 times.
✗ Branch 1 not taken.
2721 set_semijoin_embedding();
5280
1/2
✓ Branch 0 taken 2721 times.
✗ Branch 1 not taken.
2721 query_block->update_semijoin_strategies(thd);
5281 }
5282
5283
3/4
✓ Branch 0 taken 1815657 times.
✓ Branch 1 taken 96354 times.
✓ Branch 2 taken 1815673 times.
✗ Branch 3 not taken.
1912030 if (!plan_is_const()) optimize_keyuse();
5284
5285 1912027 allow_outer_refs = true;
5286
5287
5/8
✓ Branch 0 taken 2721 times.
✓ Branch 1 taken 1909306 times.
✓ Branch 2 taken 2721 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2721 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1912027 times.
1912027 if (sj_nests && optimize_semijoin_nests_for_materialization(this))
5288 return true;
5289
5290 // Choose the table order based on analysis done so far.
5291
4/6
✓ Branch 0 taken 1912029 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1912032 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 1912022 times.
1912027 if (Optimize_table_order(thd, this, nullptr).choose_table_order())
5292 10 return true;
5293
5294
3/4
✓ Branch 0 taken 1912021 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1912019 times.
1912022 DBUG_EXECUTE_IF("bug13820776_1", thd->killed = THD::KILL_QUERY;);
5295
7/8
✓ Branch 0 taken 1912013 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1912018 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1912017 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 1912017 times.
1912021 if (thd->killed || thd->is_error()) return true;
5296
5297 // If this is a subquery, decide between In-to-exists and materialization
5298
7/8
✓ Branch 0 taken 81721 times.
✓ Branch 1 taken 1830294 times.
✓ Branch 2 taken 81723 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 81716 times.
✓ Branch 6 taken 7 times.
✓ Branch 7 taken 1912010 times.
1912017 if (query_expression()->item && decide_subquery_strategy()) return true;
5299
5300
1/2
✓ Branch 0 taken 1911996 times.
✗ Branch 1 not taken.
1912010 refine_best_rowcount();
5301
5302 3824121 if (!(thd->variables.option_bits & OPTION_BIG_SELECTS) &&
5303
6/6
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 1911867 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 116 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 1911983 times.
1912009 best_read > (double)thd->variables.max_join_size &&
5304
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 !thd->lex->is_explain()) { /* purecov: inspected */
5305
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 my_error(ER_TOO_BIG_SELECT, MYF(0));
5306 13 error = -1;
5307 13 return true;
5308 }
5309
5310 1911983 positions = nullptr; // But keep best_positions for get_best_combination
5311
5312 // Generate an execution plan from the found optimal join order.
5313
2/4
✓ Branch 0 taken 1911992 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1911992 times.
1911983 if (get_best_combination()) return true;
5314
5315 // Cleanup after update_ref_and_keys has added keys for derived tables.
5316
3/4
✓ Branch 0 taken 145210 times.
✓ Branch 1 taken 1766782 times.
✓ Branch 2 taken 145210 times.
✗ Branch 3 not taken.
1911992 if (query_block->materialized_derived_table_count) finalize_derived_keys();
5317
5318 // No need for this struct after new JOIN_TAB array is set up.
5319 1911992 best_positions = nullptr;
5320
5321 // Some called function may still set error status unnoticed
5322
2/4
✓ Branch 0 taken 1911989 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1911989 times.
1911992 if (thd->is_error()) return true;
5323
5324 // There is at least one empty const table
5325
2/2
✓ Branch 0 taken 8533 times.
✓ Branch 1 taken 1903456 times.
1911989 if (const_table_map != found_const_table_map)
5326 8533 zero_result_cause = "no matching row in const table";
5327
5328 1911989 return false;
5329 1912115 }
5330
5331 /**
5332 Initialize scratch arrays for the join order optimization
5333
5334 @returns false if success, true if error
5335
5336 @note If something fails during initialization, JOIN::cleanup()
5337 will free anything that has been partially allocated and set up.
5338 Arrays are created in the execution mem_root, so they will be
5339 deleted automatically when the mem_root is re-initialized.
5340 */
5341
5342 1912108 bool JOIN::init_planner_arrays() {
5343 // Up to one extra slot per semi-join nest is needed (if materialized)
5344 1912108 const uint sj_nests = query_block->sj_nests.size();
5345 1912121 const uint table_count = query_block->leaf_table_count;
5346
5347
3/4
✓ Branch 0 taken 1912120 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1912124 times.
✗ Branch 3 not taken.
1912121 assert(primary_tables == 0 && tables == 0);
5348
5349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1912120 times.
1912124 if (!(join_tab = alloc_jtab_array(thd, table_count))) return true;
5350
5351 /*
5352 We add 2 cells:
5353 - because planning stage uses 0-termination so needs +1
5354 - because after get_best_combination, we don't use 0-termination but
5355 need +2, to host at most 2 tmp sort/group/distinct tables.
5356 */
5357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1912122 times.
1912122 if (!(best_ref = (JOIN_TAB **)thd->alloc(
5358 sizeof(JOIN_TAB *) *
5359 1912120 (table_count + sj_nests + 2 + m_windows.elements))))
5360 return true;
5361
5362 // sort/group tmp tables have no map
5363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1912125 times.
1912125 if (!(map2table = (JOIN_TAB **)thd->alloc(sizeof(JOIN_TAB *) *
5364 1912122 (table_count + sj_nests))))
5365 return true;
5366
5367
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1912124 times.
1912125 if (!(positions = new (thd->mem_root) POSITION[table_count])) return true;
5368
5369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1912124 times.
1912124 if (!(best_positions = new (thd->mem_root) POSITION[table_count + sj_nests]))
5370 return true;
5371
5372 /*
5373 Initialize data structures for tables to be joined.
5374 Initialize dependencies between tables.
5375 */
5376 1912124 JOIN_TAB **best_ref_p = best_ref;
5377 1912124 TABLE_LIST *tl = query_block->leaf_tables;
5378
5379
2/2
✓ Branch 0 taken 3928595 times.
✓ Branch 1 taken 1912115 times.
5840710 for (JOIN_TAB *tab = join_tab; tl; tab++, tl = tl->next_leaf, best_ref_p++) {
5380 3928595 *best_ref_p = tab;
5381 3928595 TABLE *const table = tl->table;
5382 3928595 tab->table_ref = tl;
5383 3928595 tab->set_table(table);
5384 3928588 const int err = tl->fetch_number_of_rows();
5385
5386 // Initialize the cost model for the table
5387 3928603 table->init_cost_model(cost_model());
5388
5389
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3928602 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3928594 DBUG_EXECUTE_IF("bug11747970_raise_error", {
5390 if (!err) {
5391 my_error(ER_UNKNOWN_ERROR, MYF(0));
5392 return true;
5393 }
5394 });
5395
5396
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3928600 times.
3928602 if (err) {
5397 2 table->file->print_error(err, MYF(0));
5398 2 return true;
5399 }
5400 3928600 all_table_map |= tl->map();
5401 3928601 tab->set_join(this);
5402
5403
6/6
✓ Branch 0 taken 3868357 times.
✓ Branch 1 taken 60241 times.
✓ Branch 2 taken 2383 times.
✓ Branch 3 taken 3865970 times.
✓ Branch 4 taken 62624 times.
✓ Branch 5 taken 3865970 times.
3928596 if (tl->is_updated() || tl->is_deleted()) {
5404 // As we update or delete rows, we can't read the index
5405 62624 table->no_keyread = true;
5406 }
5407
5408 3928594 tab->dependent = tl->dep_tables; // Initialize table dependencies
5409
2/2
✓ Branch 0 taken 713 times.
✓ Branch 1 taken 3927874 times.
3928594 if (query_block->is_recursive()) {
5410
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 497 times.
713 if (query_block->recursive_reference != tl)
5411 // Recursive reference must go first
5412 216 tab->dependent |= query_block->recursive_reference->map();
5413 else {
5414 // Recursive reference mustn't use any index
5415 497 table->covering_keys.clear_all();
5416 497 table->keys_in_use_for_group_by.clear_all();
5417 497 table->keys_in_use_for_order_by.clear_all();
5418 }
5419 }
5420
2/2
✓ Branch 0 taken 251471 times.
✓ Branch 1 taken 3677117 times.
3928588 if (tl->schema_table) table->file->stats.records = 2;
5421 3928588 table->quick_condition_rows = table->file->stats.records;
5422
5423 3928588 tab->init_join_cond_ref(tl);
5424
5425
2/2
✓ Branch 0 taken 3759 times.
✓ Branch 1 taken 3924821 times.
3928583 if (tl->outer_join_nest()) {
5426 // tab belongs to a nested join, maybe to several embedding joins
5427 3759 tab->embedding_map = 0;
5428
2/2
✓ Branch 0 taken 4097 times.
✓ Branch 1 taken 3759 times.
7856 for (TABLE_LIST *embedding = tl->embedding; embedding;
5429 4097 embedding = embedding->embedding) {
5430 4097 NESTED_JOIN *const nested_join = embedding->nested_join;
5431 4097 tab->embedding_map |= nested_join->nj_map;
5432 4097 tab->dependent |= embedding->dep_tables;
5433 }
5434
2/2
✓ Branch 0 taken 401518 times.
✓ Branch 1 taken 3523307 times.
3924821 } else if (tab->join_cond()) {
5435 // tab is the only inner table of an outer join
5436 401518 tab->embedding_map = 0;
5437
2/2
✓ Branch 0 taken 3780 times.
✓ Branch 1 taken 401518 times.
405298 for (TABLE_LIST *embedding = tl->embedding; embedding;
5438 3780 embedding = embedding->embedding)
5439 3780 tab->embedding_map |= embedding->nested_join->nj_map;
5440 }
5441
5442
6/6
✓ Branch 0 taken 143724 times.
✓ Branch 1 taken 3784862 times.
✓ Branch 2 taken 564 times.
✓ Branch 3 taken 143160 times.
✓ Branch 4 taken 564 times.
✓ Branch 5 taken 3928022 times.
3928584 if (tl->is_derived() && tl->derived_query_expression()->m_lateral_deps)
5443 564 has_lateral = true;
5444
5445 3928586 tables++; // Count number of initialized tables
5446 }
5447
5448 1912115 primary_tables = tables;
5449 1912115 *best_ref_p = nullptr; // Last element of array must be NULL
5450
5451 1912115 return false;
5452 }
5453
5454 /**
5455 Propagate dependencies between tables due to outer join relations.
5456
5457 @returns false if success, true if error
5458
5459 Build transitive closure for relation 'to be dependent on'.
5460 This will speed up the plan search for many cases with outer joins,
5461 as well as allow us to catch illegal cross references.
5462 Warshall's algorithm is used to build the transitive closure.
5463 As we may restart the outer loop up to 'table_count' times, the
5464 complexity of the algorithm is O((number of tables)^3).
5465 However, most of the iterations will be shortcircuited when
5466 there are no dependencies to propagate.
5467 */
5468
5469 151286 bool JOIN::propagate_dependencies() {
5470
2/2
✓ Branch 0 taken 970017 times.
✓ Branch 1 taken 151291 times.
1121308 for (uint i = 0; i < tables; i++) {
5471
2/2
✓ Branch 0 taken 564050 times.
✓ Branch 1 taken 405967 times.
970017 if (!join_tab[i].dependent) continue;
5472
5473 // Add my dependencies to other tables depending on me
5474 uint j;
5475 JOIN_TAB *tab;
5476
2/2
✓ Branch 0 taken 2603079 times.
✓ Branch 1 taken 405944 times.
3009023 for (j = 0, tab = join_tab; j < tables; j++, tab++) {
5477
2/2
✓ Branch 0 taken 258195 times.
✓ Branch 1 taken 2344889 times.
2603079 if (tab->dependent & join_tab[i].table_ref->map()) {
5478 258195 const table_map was_dependent = tab->dependent;
5479 258195 tab->dependent |= join_tab[i].dependent;
5480 /*
5481 If we change dependencies for a table we already have
5482 processed: Redo dependency propagation from this table.
5483 */
5484
4/4
✓ Branch 0 taken 271 times.
✓ Branch 1 taken 257924 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 243 times.
258195 if (i > j && tab->dependent != was_dependent) {
5485 28 i = j - 1;
5486 28 break;
5487 }
5488 }
5489 }
5490 }
5491
5492 151291 JOIN_TAB *const tab_end = join_tab + tables;
5493
2/2
✓ Branch 0 taken 969910 times.
✓ Branch 1 taken 151265 times.
1121175 for (JOIN_TAB *tab = join_tab; tab < tab_end; tab++) {
5494
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 969884 times.
969910 if ((tab->dependent & tab->table_ref->map())) return true;
5495 }
5496
5497 151265 return false;
5498 }
5499
5500 /**
5501 Extract const tables based on row counts.
5502
5503 @returns false if success, true if error
5504
5505 This extraction must be done for each execution.
5506 Tables containing exactly zero or one rows are marked as const, but
5507 notice the additional constraints checked below.
5508 Tables that are extracted have their rows read before actual execution
5509 starts and are placed in the beginning of the join_tab array.
5510 Thus, they do not take part in join order optimization process,
5511 which can significantly reduce the optimization time.
5512 The data read from these tables can also be regarded as "constant"
5513 throughout query execution, hence the column values can be used for
5514 additional constant propagation and extraction of const tables based
5515 on eq-ref properties.
5516
5517 The tables are given the type JT_SYSTEM.
5518 */
5519
5520 1908147 bool JOIN::extract_const_tables() {
5521 enum enum_const_table_extraction {
5522 extract_no_table = 0,
5523 extract_empty_table = 1,
5524 extract_const_table = 2
5525 };
5526
5527 1908147 JOIN_TAB *const tab_end = join_tab + tables;
5528
2/2
✓ Branch 0 taken 3924471 times.
✓ Branch 1 taken 1908170 times.
5832641 for (JOIN_TAB *tab = join_tab; tab < tab_end; tab++) {
5529 3924471 TABLE *const table = tab->table();
5530 3924495 TABLE_LIST *const tl = tab->table_ref;
5531 3924495 enum enum_const_table_extraction extract_method = extract_const_table;
5532
5533 3924495 const bool all_partitions_pruned_away = table->all_partitions_pruned_away;
5534
5535
2/2
✓ Branch 0 taken 3759 times.
✓ Branch 1 taken 3920746 times.
3924495 if (tl->outer_join_nest()) {
5536 /*
5537 Table belongs to a nested join, no candidate for const table extraction.
5538 */
5539 3759 extract_method = extract_no_table;
5540
5/6
✓ Branch 0 taken 10161 times.
✓ Branch 1 taken 3910585 times.
✓ Branch 2 taken 10161 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10161 times.
✓ Branch 5 taken 3910585 times.
3920746 } else if (tl->embedding && tl->embedding->is_sj_or_aj_nest()) {
5541 /*
5542 Table belongs to a semi-join.
5543 We do not currently pull out const tables from semi-join nests.
5544 */
5545 10161 extract_method = extract_no_table;
5546
2/2
✓ Branch 0 taken 397694 times.
✓ Branch 1 taken 3512877 times.
3910585 } else if (tab->join_cond()) {
5547 // tab is the only inner table of an outer join, extract empty tables
5548 397694 extract_method = extract_empty_table;
5549 }
5550
4/4
✓ Branch 0 taken 13920 times.
✓ Branch 1 taken 397693 times.
✓ Branch 2 taken 3512877 times.
✓ Branch 3 taken 1 times.
3924491 switch (extract_method) {
5551 13920 case extract_no_table:
5552 13920 break;
5553
5554 397693 case extract_empty_table:
5555 // Extract tables with zero rows, but only if statistics are exact
5556
5/6
✓ Branch 0 taken 397628 times.
✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 397628 times.
✓ Branch 4 taken 65 times.
✓ Branch 5 taken 397629 times.
397759 if ((table->file->stats.records == 0 || all_partitions_pruned_away) &&
5557
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 1 times.
65 (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT))
5558 65 mark_const_table(tab, nullptr);
5559 397694 break;
5560
5561 3512877 case extract_const_table:
5562 /*
5563 Extract tables with zero or one rows, but do not extract tables that
5564 1. are dependent upon other tables, or
5565 2. have no exact statistics, or
5566 3. are full-text searched
5567 */
5568
3/4
✓ Branch 0 taken 2871832 times.
✓ Branch 1 taken 641041 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2871832 times.
3512873 if ((table->s->system || table->file->stats.records <= 1 ||
5569 641045 all_partitions_pruned_away) &&
5570
2/2
✓ Branch 0 taken 640609 times.
✓ Branch 1 taken 436 times.
641045 !tab->dependent && // 1
5571
6/6
✓ Branch 0 taken 3512873 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 14501 times.
✓ Branch 3 taken 626105 times.
✓ Branch 4 taken 14464 times.
✓ Branch 5 taken 3498412 times.
7040257 (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && // 2
5572
2/2
✓ Branch 0 taken 14464 times.
✓ Branch 1 taken 39 times.
14501 !tl->is_fulltext_searched()) // 3
5573 14464 mark_const_table(tab, nullptr);
5574 3512879 break;
5575 }
5576 }
5577
5578 // Read const tables (tables matching no more than 1 rows)
5579
2/2
✓ Branch 0 taken 1893980 times.
✓ Branch 1 taken 14190 times.
1908170 if (!const_tables) return false;
5580
5581 28721 for (POSITION *p_pos = positions, *p_end = p_pos + const_tables;
5582
2/2
✓ Branch 0 taken 14530 times.
✓ Branch 1 taken 14191 times.
28721 p_pos < p_end; p_pos++) {
5583 14530 JOIN_TAB *const tab = p_pos->table;
5584 14530 const int status = join_read_const_table(tab, p_pos);
5585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14531 times.
14531 if (status > 0)
5586 return true;
5587
2/2
✓ Branch 0 taken 9850 times.
✓ Branch 1 taken 4681 times.
14531 else if (status == 0) {
5588 9850 found_const_table_map |= tab->table_ref->map();
5589 9850 tab->table_ref->optimized_away = true;
5590 }
5591 }
5592
5593 14191 return false;
5594 }
5595
5596 /**
5597 Extract const tables based on functional dependencies.
5598
5599 @returns false if success, true if error
5600
5601 This extraction must be done for each execution.
5602
5603 Mark as const the tables that
5604 - are functionally dependent on constant values, or
5605 - are inner tables of an outer join and contain exactly zero or one rows
5606
5607 Tables that are extracted have their rows read before actual execution
5608 starts and are placed in the beginning of the join_tab array, just as
5609 described for JOIN::extract_const_tables().
5610
5611 The tables are given the type JT_CONST.
5612 */
5613
5614 1908275 bool JOIN::extract_func_dependent_tables() {
5615 // loop until no more const tables are found
5616 bool ref_changed;
5617 // Tables referenced by others; if they're const the others may be too.
5618 table_map found_ref;
5619 do {
5620 1908275 more_const_tables_found:
5621 1908275 ref_changed = false;
5622 1908275 found_ref = 0;
5623
5624 // Loop over all tables that are not already determined to be const
5625
2/2
✓ Branch 0 taken 3910232 times.
✓ Branch 1 taken 1908152 times.
5818384 for (JOIN_TAB **pos = best_ref + const_tables; *pos; pos++) {
5626 3910232 JOIN_TAB *const tab = *pos;
5627 3910232 TABLE *const table = tab->table();
5628 3910249 TABLE_LIST *const tl = tab->table_ref;
5629 /*
5630 If equi-join condition by a key is null rejecting and after a
5631 substitution of a const table the key value happens to be null
5632 then we can state that there are no matches for this equi-join.
5633 */
5634 3910249 Key_use *keyuse = tab->keyuse();
5635
8/8
✓ Branch 0 taken 2590970 times.
✓ Branch 1 taken 1319286 times.
✓ Branch 2 taken 397148 times.
✓ Branch 3 taken 2193822 times.
✓ Branch 4 taken 396977 times.
✓ Branch 5 taken 171 times.
✓ Branch 6 taken 396977 times.
✓ Branch 7 taken 3513279 times.
3910256 if (keyuse && tab->join_cond() && !tab->embedding_map) {
5636 /*
5637 When performing an outer join operation if there are no matching rows
5638 for the single row of the outer table all the inner tables are to be
5639 null complemented and thus considered as constant tables.
5640 Here we apply this consideration to the case of outer join operations
5641 with a single inner table only because the case with nested tables
5642 would require a more thorough analysis.
5643 TODO. Apply single row substitution to null complemented inner tables
5644 for nested outer join operations.
5645 */
5646
2/2
✓ Branch 0 taken 513824 times.
✓ Branch 1 taken 396931 times.
910755 while (keyuse->table_ref == tl) {
5647 513824 if (!(keyuse->val->used_tables() & ~const_table_map) &&
5648
8/8
✓ Branch 0 taken 113745 times.
✓ Branch 1 taken 400090 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 113675 times.
✓ Branch 4 taken 49 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 43 times.
✓ Branch 7 taken 513778 times.
513884 keyuse->val->is_null() && keyuse->null_rejecting &&
5649
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 43 times.
49 (tl->embedding == nullptr ||
5650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 !tl->embedding->is_sj_or_aj_nest())) {
5651 43 table->set_null_row();
5652 43 table->const_table = true;
5653 43 found_const_table_map |= tl->map();
5654 43 mark_const_table(tab, keyuse);
5655 48 goto more_const_tables_found;
5656 }
5657 513778 keyuse++;
5658 }
5659 }
5660
5661
2/2
✓ Branch 0 taken 407702 times.
✓ Branch 1 taken 3502508 times.
3910210 if (tab->dependent) // If dependent on some table
5662 {
5663 // All dependent tables must be const
5664
2/2
✓ Branch 0 taken 407363 times.
✓ Branch 1 taken 339 times.
407702 if (tab->dependent & ~const_table_map) {
5665 407363 found_ref |= tab->dependent;
5666 407363 continue;
5667 }
5668 /*
5669 Mark a dependent table as constant if
5670 1. it has exactly zero or one rows (it is a system table), and
5671 2. it is not within a nested outer join, and
5672 3. it does not have an expensive outer join condition.
5673 This is because we have to determine whether an outer-joined table
5674 has a real row or a null-extended row in the optimizer phase.
5675 We have no possibility to evaluate its join condition at
5676 execution time, when it is marked as a system table.
5677 */
5678 809 if (table->file->stats.records <= 1L && // 1
5679
4/4
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 44 times.
202 (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && // 1
5680
6/6
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 210 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 29 times.
✓ Branch 5 taken 312 times.
554 !tl->outer_join_nest() && // 2
5681
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2 times.
40 !(tab->join_cond() && tab->join_cond()->is_expensive())) // 3
5682 { // system table
5683 29 mark_const_table(tab, nullptr);
5684 const int status =
5685 29 join_read_const_table(tab, positions + const_tables - 1);
5686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
29 if (status > 0)
5687 return true;
5688
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 14 times.
29 else if (status == 0)
5689 15 found_const_table_map |= tl->map();
5690 29 continue;
5691 29 }
5692 }
5693
5694 // Check if table can be read by key or table only uses const refs
5695
5696
2/2
✓ Branch 0 taken 2191649 times.
✓ Branch 1 taken 1311149 times.
3502820 if ((keyuse = tab->keyuse())) {
5697
2/2
✓ Branch 0 taken 3473616 times.
✓ Branch 1 taken 2106287 times.
5579903 while (keyuse->table_ref == tl) {
5698 3473616 Key_use *const start_keyuse = keyuse;
5699 3473616 const uint key = keyuse->key;
5700 3473616 tab->keys().set_bit(key); // QQ: remove this ?
5701
5702 3473625 table_map refs = 0;
5703
2/4
✓ Branch 0 taken 3473631 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3473630 times.
✗ Branch 3 not taken.
3473625 Key_map const_ref, eq_part;
5704 do {
5705
7/8
✓ Branch 0 taken 4655097 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4653031 times.
✓ Branch 3 taken 2066 times.
✓ Branch 4 taken 4652783 times.
✓ Branch 5 taken 248 times.
✓ Branch 6 taken 4652784 times.
✓ Branch 7 taken 2313 times.
4655096 if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize) {
5706
2/2
✓ Branch 0 taken 873263 times.
✓ Branch 1 taken 3779521 times.
4652784 if (!((~found_const_table_map) & keyuse->used_tables))
5707 873263 const_ref.set_bit(keyuse->keypart);
5708 else
5709 3779521 refs |= keyuse->used_tables;
5710 4652785 eq_part.set_bit(keyuse->keypart);
5711 }
5712 4655089 keyuse++;
5713
4/4
✓ Branch 0 taken 2463835 times.
✓ Branch 1 taken 2191254 times.
✓ Branch 2 taken 1181466 times.
✓ Branch 3 taken 1282369 times.
4655089 } while (keyuse->table_ref == tl && keyuse->key == key);
5714
5715 /*
5716 Extract const tables with proper key dependencies.
5717 Exclude tables that
5718 1. are full-text searched, or
5719 2. are part of nested outer join, or
5720 3. are part of semi-join, or
5721 4. have an expensive outer join condition.
5722 5. are blocked by handler for const table optimize.
5723 6. are not going to be used, typically because they are streamed
5724 instead of materialized
5725 (see Query_expression::can_materialize_directly_into_result()).
5726 */
5727 3473623 if (eq_part.is_prefix(table->key_info[key].user_defined_key_parts) &&
5728
4/4
✓ Branch 0 taken 2411416 times.
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 2411385 times.
✓ Branch 3 taken 38 times.
4822880 !tl->is_fulltext_searched() && // 1
5729 2411416 !tl->outer_join_nest() && // 2
5730
6/6
✓ Branch 0 taken 5617 times.
✓ Branch 1 taken 2405768 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 5616 times.
✓ Branch 4 taken 76 times.
✓ Branch 5 taken 2405692 times.
4817153 !(tl->embedding && tl->embedding->is_sj_or_aj_nest()) && // 3
5731
2/4
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
2405845 !(tab->join_cond() && tab->join_cond()->is_expensive()) && // 4
5732
7/8
✓ Branch 0 taken 2411457 times.
✓ Branch 1 taken 1062163 times.
✓ Branch 2 taken 2405761 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2405026 times.
✓ Branch 5 taken 731 times.
✓ Branch 6 taken 2405026 times.
✓ Branch 7 taken 1068593 times.
8290846 !(table->file->ha_table_flags() & HA_BLOCK_CONST_TABLE) && // 5
5733 2405761 table->is_created()) { // 6
5734
2/2
✓ Branch 0 taken 1885431 times.
✓ Branch 1 taken 519595 times.
2405026 if (table->key_info[key].flags & HA_NOSAME) {
5735
2/2
✓ Branch 0 taken 85368 times.
✓ Branch 1 taken 1800064 times.
1885431 if (const_ref == eq_part) { // Found everything for ref.
5736 85368 ref_changed = true;
5737
1/2
✓ Branch 0 taken 85368 times.
✗ Branch 1 not taken.
85368 mark_const_table(tab, start_keyuse);
5738
3/4
✓ Branch 0 taken 85368 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 85366 times.
85368 if (create_ref_for_key(this, tab, start_keyuse,
5739 found_const_table_map))
5740 87 return true;
5741 const int status =
5742
1/2
✓ Branch 0 taken 85366 times.
✗ Branch 1 not taken.
85366 join_read_const_table(tab, positions + const_tables - 1);
5743
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 85281 times.
85366 if (status > 0)
5744 85 return true;
5745
2/2
✓ Branch 0 taken 82457 times.
✓ Branch 1 taken 2824 times.
85281 else if (status == 0)
5746 82457 found_const_table_map |= tl->map();
5747 85281 break;
5748 } else
5749 1800064 found_ref |= refs; // Table is const if all refs are const
5750
2/2
✓ Branch 0 taken 73713 times.
✓ Branch 1 taken 445883 times.
519595 } else if (const_ref == eq_part)
5751 73713 tab->const_keys.set_bit(key);
5752 }
5753 }
5754 }
5755 }
5756 } while
5757 /*
5758 A new const table appeared, that is referenced by others, so re-check
5759 others:
5760 */
5761
4/4
✓ Branch 0 taken 654 times.
✓ Branch 1 taken 1907498 times.
✓ Branch 2 taken 82 times.
✓ Branch 3 taken 572 times.
1908152 ((const_table_map & found_ref) && ref_changed);
5762
5763 1908070 return false;
5764 }
5765
5766 /**
5767 Update info on indexes that can be used for search lookups as
5768 reading const tables may has added new sargable predicates.
5769 */
5770
5771 90395 void JOIN::update_sargable_from_const(SARGABLE_PARAM *sargables) {
5772
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 90395 times.
90475 for (; sargables->field; sargables++) {
5773 80 Field *const field = sargables->field;
5774 80 JOIN_TAB *const tab = field->table->reginfo.join_tab;
5775 80 Key_map possible_keys = field->key_start;
5776 80 possible_keys.intersect(field->table->keys_in_use_for_query);
5777 80 bool is_const = true;
5778
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 80 times.
196 for (uint j = 0; j < sargables->num_values; j++)
5779
1/2
✓ Branch 0 taken 116 times.
✗ Branch 1 not taken.
116 is_const &= sargables->arg_value[j]->const_item();
5780
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 28 times.
80 if (is_const) {
5781 52 tab->const_keys.merge(possible_keys);
5782 52 tab->keys().merge(possible_keys);
5783 }
5784 }
5785 90395 }
5786
5787 3828604 double find_worst_seeks(const TABLE *table, double num_rows,
5788 double table_scan_cost) {
5789 /*
5790 Set a max value for the cost of seek operations we can expect
5791 when using key lookup. This can't be too high as otherwise we
5792 are likely to use table scan.
5793 */
5794 double worst_seeks =
5795
1/2
✓ Branch 0 taken 3828621 times.
✗ Branch 1 not taken.
3828604 min(table->file->worst_seek_times(num_rows / 10), table_scan_cost * 3);
5796
1/2
✓ Branch 0 taken 3828623 times.
✗ Branch 1 not taken.
3828620 const double min_worst_seek = table->file->worst_seek_times(2.0);
5797 3828623 return std::max(worst_seeks, min_worst_seek); // Fix for small tables
5798 }
5799
5800 /**
5801 Estimate the number of matched rows for each joined table.
5802 Set up range scan for tables that have proper predicates.
5803
5804 @returns false if success, true if error
5805 */
5806
5807 1912010 bool JOIN::estimate_rowcount() {
5808 1912010 Opt_trace_context *const trace = &thd->opt_trace;
5809
1/2
✓ Branch 0 taken 1912031 times.
✗ Branch 1 not taken.
1912010 Opt_trace_object trace_wrapper(trace);
5810
1/2
✓ Branch 0 taken 1912030 times.
✗ Branch 1 not taken.
1912031 Opt_trace_array trace_records(trace, "rows_estimation");
5811
5812 1912030 JOIN_TAB *const tab_end = join_tab + tables;
5813
2/2
✓ Branch 0 taken 3928482 times.
✓ Branch 1 taken 1912053 times.
5840535 for (JOIN_TAB *tab = join_tab; tab < tab_end; tab++) {
5814
1/2
✓ Branch 0 taken 3928498 times.
✗ Branch 1 not taken.
3928482 Opt_trace_object trace_table(trace);
5815
1/2
✓ Branch 0 taken 3928496 times.
✗ Branch 1 not taken.
3928498 trace_table.add_utf8_table(tab->table_ref);
5816
6/6
✓ Branch 0 taken 3913943 times.
✓ Branch 1 taken 14560 times.
✓ Branch 2 taken 85324 times.
✓ Branch 3 taken 3828616 times.
✓ Branch 4 taken 99884 times.
✓ Branch 5 taken 3828616 times.
3928496 if (tab->type() == JT_SYSTEM || tab->type() == JT_CONST) {
5817
1/2
✓ Branch 0 taken 99884 times.
✗ Branch 1 not taken.
99884 trace_table.add("rows", 1)
5818
1/2
✓ Branch 0 taken 99884 times.
✗ Branch 1 not taken.
99884 .add("cost", 1)
5819
3/4
✓ Branch 0 taken 14560 times.
✓ Branch 1 taken 85323 times.
✓ Branch 2 taken 99884 times.
✗ Branch 3 not taken.
99883 .add_alnum("table_type",
5820 99884 (tab->type() == JT_SYSTEM) ? "system" : "const")
5821
1/2
✓ Branch 0 taken 99884 times.
✗ Branch 1 not taken.
99884 .add("empty", tab->table()->has_null_row());
5822
5823 // Only one matching row and one block to read
5824 99884 tab->set_records(tab->found_records = 1);
5825
1/2
✓ Branch 0 taken 99884 times.
✗ Branch 1 not taken.
99884 tab->worst_seeks = tab->table()->file->worst_seek_times(1.0);
5826 99884 tab->read_time = tab->worst_seeks;
5827 99884 continue;
5828 }
5829 // Approximate number of found rows and cost to read them
5830 3828616 tab->set_records(tab->found_records = tab->table()->file->stats.records);
5831
1/2
✓ Branch 0 taken 3828607 times.
✗ Branch 1 not taken.
3828600 const Cost_estimate table_scan_time = tab->table()->file->table_scan_cost();
5832 3828607 tab->read_time = table_scan_time.total_cost();
5833
5834 3828620 tab->worst_seeks =
5835
1/2
✓ Branch 0 taken 3828620 times.
✗ Branch 1 not taken.
3828612 find_worst_seeks(tab->table(), tab->found_records, tab->read_time);
5836
5837 /*
5838 Add to tab->const_keys the indexes for which all group fields or
5839 all select distinct fields participate in one index.
5840 Add to tab->skip_scan_keys indexes which can be used for skip
5841 scan access if no aggregates are present.
5842 */
5843
1/2
✓ Branch 0 taken 3828606 times.
✗ Branch 1 not taken.
3828620 add_loose_index_scan_and_skip_scan_keys(this, tab);
5844
5845 /*
5846 Perform range analysis if there are keys it could use (1).
5847 Don't do range analysis if on the inner side of an outer join (2).
5848 Do range analysis if on the inner side of a semi-join (3).
5849 */
5850 3828606 TABLE_LIST *const tl = tab->table_ref;
5851 3828606 if ((!tab->const_keys.is_clear_all() ||
5852
6/6
✓ Branch 0 taken 3293722 times.
✓ Branch 1 taken 534881 times.
✓ Branch 2 taken 22516 times.
✓ Branch 3 taken 3271216 times.
✓ Branch 4 taken 556993 times.
✓ Branch 5 taken 3271620 times.
4386000 !tab->skip_scan_keys.is_clear_all()) && // (1)
5853
2/2
✓ Branch 0 taken 603 times.
✓ Branch 1 taken 556794 times.
557397 (!tl->embedding || // (2)
5854
3/4
✓ Branch 0 taken 603 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 199 times.
✓ Branch 3 taken 404 times.
603 (tl->embedding && tl->embedding->is_sj_or_aj_nest()))) // (3)
5855 {
5856 /*
5857 This call fills tab->range_scan() with the best QUICK access method
5858 possible for this table, and only if it's better than table scan.
5859 It also fills tab->needed_reg.
5860 */
5861
1/2
✓ Branch 0 taken 556993 times.
✗ Branch 1 not taken.
556993 ha_rows records = get_quick_record_count(thd, tab, row_limit);
5862
5863
5/8
✓ Branch 0 taken 1095 times.
✓ Branch 1 taken 555898 times.
✓ Branch 2 taken 1095 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1095 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 556993 times.
556993 if (records == 0 && thd->is_error()) return true;
5864
5865 /*
5866 Check for "impossible range", but make sure that we do not attempt
5867 to mark semi-joined tables as "const" (only semi-joined tables that
5868 are functionally dependent can be marked "const", and subsequently
5869 pulled out of their semi-join nests).
5870 */
5871
5/6
✓ Branch 0 taken 1095 times.
✓ Branch 1 taken 555898 times.
✓ Branch 2 taken 1095 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1085 times.
✓ Branch 5 taken 555908 times.
558088 if (records == 0 && tab->table()->reginfo.impossible_range &&
5872
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1085 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
1095 (!(tl->embedding && tl->embedding->is_sj_or_aj_nest()))) {
5873 /*
5874 Impossible WHERE condition or join condition
5875 In case of join cond, mark that one empty NULL row is matched.
5876 In case of WHERE, don't set found_const_table_map to get the
5877 caller to abort with a zero row result.
5878 */
5879
1/2
✓ Branch 0 taken 1085 times.
✗ Branch 1 not taken.
1085 mark_const_table(tab, nullptr);
5880 1085 tab->set_type(JT_CONST); // Override setting made in mark_const_table()
5881
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1081 times.
1085 if (tab->join_cond()) {
5882 // Generate an empty row
5883
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 trace_table.add("returning_empty_null_row", true)
5884
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 .add_alnum("cause", "impossible_on_condition");
5885 4 found_const_table_map |= tl->map();
5886 4 tab->table()->set_null_row(); // All fields are NULL
5887 } else {
5888
2/4
✓ Branch 0 taken 1081 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1081 times.
✗ Branch 3 not taken.
1081 trace_table.add("rows", 0).add_alnum("cause",
5889 "impossible_where_condition");
5890 }
5891 }
5892
2/2
✓ Branch 0 taken 250484 times.
✓ Branch 1 taken 306509 times.
556993 if (records != HA_POS_ERROR) {
5893 250484 tab->found_records = records;
5894
2/2
✓ Branch 0 taken 249378 times.
✓ Branch 1 taken 1106 times.
250484 tab->read_time = tab->range_scan() ? tab->range_scan()->cost : 0.0;
5895 }
5896 } else {
5897
1/2
✓ Branch 0 taken 3271605 times.
✗ Branch 1 not taken.
6543245 Opt_trace_object(trace, "table_scan")
5898
1/2
✓ Branch 0 taken 3271624 times.
✗ Branch 1 not taken.
3271605 .add("rows", tab->found_records)
5899
1/2
✓ Branch 0 taken 3271625 times.
✗ Branch 1 not taken.
3271624 .add("cost", tab->read_time);
5900 }
5901
2/3
✓ Branch 0 taken 3828622 times.
✓ Branch 1 taken 99883 times.
✗ Branch 2 not taken.
3928506 }
5902
5903 1912053 return false;
5904 1912052 }
5905
5906 /**
5907 Set semi-join embedding join nest pointers.
5908
5909 Set pointer to embedding semi-join nest for all semi-joined tables.
5910 This is the closest semi-join or anti-join nest.
5911 Note that this must be done for every table inside all semi-join nests,
5912 even for tables within outer join nests embedded in semi-join nests.
5913 A table can never be part of multiple semi-join nests, hence no
5914 ambiguities can ever occur.
5915 Note also that the pointer is not set for TABLE_LIST objects that
5916 are outer join nests within semi-join nests.
5917 */
5918
5919 2721 void JOIN::set_semijoin_embedding() {
5920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2721 times.
2721 assert(!query_block->sj_nests.empty());
5921
5922 2721 JOIN_TAB *const tab_end = join_tab + primary_tables;
5923
5924
2/2
✓ Branch 0 taken 15794 times.
✓ Branch 1 taken 2721 times.
18515 for (JOIN_TAB *tab = join_tab; tab < tab_end; tab++) {
5925 15794 tab->emb_sj_nest = nullptr;
5926
2/2
✓ Branch 0 taken 10536 times.
✓ Branch 1 taken 15794 times.
26330 for (TABLE_LIST *tl = tab->table_ref; tl->embedding; tl = tl->embedding) {
5927
2/2
✓ Branch 0 taken 10400 times.
✓ Branch 1 taken 136 times.
10536 if (tl->embedding->is_sj_or_aj_nest()) {
5928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10400 times.
10400 assert(!tab->emb_sj_nest);
5929 10400 tab->emb_sj_nest = tl->embedding;
5930 // Let the up-walk continue, to assert there's no AJ/SJ nest above.
5931 }
5932 }
5933 }
5934 2721 }
5935
5936 /**
5937 @brief Check if semijoin's compared types allow materialization.
5938
5939 @param[in,out] sj_nest Semi-join nest containing information about correlated
5940 expressions. Set nested_join->sjm.scan_allowed to true if
5941 MaterializeScan strategy allowed. Set nested_join->sjm.lookup_allowed
5942 to true if MaterializeLookup strategy allowed
5943
5944 @details
5945 This is a temporary fix for BUG#36752.
5946
5947 There are two subquery materialization strategies for semijoin:
5948
5949 1. Materialize and do index lookups in the materialized table. See
5950 BUG#36752 for description of restrictions we need to put on the
5951 compared expressions.
5952
5953 In addition, since indexes are not supported for BLOB columns,
5954 this strategy can not be used if any of the columns in the
5955 materialized table will be BLOB/GEOMETRY columns. (Note that
5956 also columns for non-BLOB values that may be greater in size
5957 than CONVERT_IF_BIGGER_TO_BLOB, will be represented as BLOB
5958 columns.)
5959
5960 2. Materialize and then do a full scan of the materialized table.
5961 The same criteria as for MaterializeLookup are applied, except that
5962 BLOB/GEOMETRY columns are allowed.
5963 */
5964
5965 2576 static void semijoin_types_allow_materialization(TABLE_LIST *sj_nest) {
5966
1/2
✓ Branch 0 taken 2576 times.
✗ Branch 1 not taken.
2576 DBUG_TRACE;
5967
5968
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2576 times.
2576 assert(sj_nest->nested_join->sj_outer_exprs.size() ==
5969 sj_nest->nested_join->sj_inner_exprs.size());
5970
5971
3/6
✓ Branch 0 taken 2576 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2576 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2576 times.
5152 if (sj_nest->nested_join->sj_outer_exprs.size() > MAX_REF_PARTS ||
5972 2576 sj_nest->nested_join->sj_outer_exprs.size() == 0) {
5973 // building an index is impossible
5974 sj_nest->nested_join->sjm.scan_allowed = false;
5975 sj_nest->nested_join->sjm.lookup_allowed = false;
5976 return;
5977 }
5978
5979 2576 sj_nest->nested_join->sjm.scan_allowed = true;
5980 2576 sj_nest->nested_join->sjm.lookup_allowed = true;
5981
5982 2576 bool blobs_involved = false;
5983 2576 uint total_lookup_index_length = 0;
5984 uint max_key_length, max_key_part_length, max_key_parts;
5985 /*
5986 Maximum lengths for keys and key parts that are supported by
5987 the temporary table storage engine(s).
5988 */
5989
1/2
✓ Branch 0 taken 2576 times.
✗ Branch 1 not taken.
2576 get_max_key_and_part_length(&max_key_length, &max_key_part_length,
5990 &max_key_parts);
5991
1/2
✓ Branch 0 taken 2576 times.
✗ Branch 1 not taken.
2576 auto it1 = sj_nest->nested_join->sj_outer_exprs.begin();
5992
1/2
✓ Branch 0 taken 2576 times.
✗ Branch 1 not taken.
2576 auto it2 = sj_nest->nested_join->sj_inner_exprs.begin();
5993
4/6
✓ Branch 0 taken 4968 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4968 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2635 times.
✓ Branch 5 taken 2333 times.
7603 while (it1 != sj_nest->nested_join->sj_outer_exprs.end() &&
5994
5/8
✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2635 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2635 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2635 times.
✓ Branch 7 taken 2333 times.
7603 it2 != sj_nest->nested_join->sj_inner_exprs.end()) {
5995
2/4
✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2635 times.
✗ Branch 3 not taken.
2635 Item *outer = *it1++;
5996
2/4
✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2635 times.
✗ Branch 3 not taken.
2635 Item *inner = *it2++;
5997
4/8
✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2635 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2635 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2635 times.
✗ Branch 7 not taken.
2635 assert(outer->real_item() && inner->real_item());
5998
3/4
✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 243 times.
✓ Branch 3 taken 2392 times.
2635 if (!types_allow_materialization(outer, inner)) {
5999 243 sj_nest->nested_join->sjm.scan_allowed = false;
6000 243 sj_nest->nested_join->sjm.lookup_allowed = false;
6001 243 return;
6002 }
6003
1/2
✓ Branch 0 taken 2392 times.
✗ Branch 1 not taken.
2392 blobs_involved |= inner->is_blob_field();
6004
6005 // Calculate the index length of materialized table
6006
1/2
✓ Branch 0 taken 2392 times.
✗ Branch 1 not taken.
2392 const uint lookup_index_length = get_key_length_tmp_table(inner);
6007
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2390 times.
2392 if (lookup_index_length > max_key_part_length)
6008 2 sj_nest->nested_join->sjm.lookup_allowed = false;
6009 2392 total_lookup_index_length += lookup_index_length;
6010 }
6011
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2331 times.
2333 if (total_lookup_index_length > max_key_length)
6012 2 sj_nest->nested_join->sjm.lookup_allowed = false;
6013
6014
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2329 times.
2333 if (blobs_involved) sj_nest->nested_join->sjm.lookup_allowed = false;
6015
6016
3/8
✓ Branch 0 taken 2333 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2333 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2333 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2333 DBUG_PRINT("info", ("semijoin_types_allow_materialization: ok, allowed"));
6017
2/2
✓ Branch 0 taken 2333 times.
✓ Branch 1 taken 243 times.
2576 }
6018
6019 /**
6020 Index dive can be skipped if the following conditions are satisfied:
6021 F1) For a single table query:
6022 a) FORCE INDEX applies to a single index.
6023 b) No subquery is present.
6024 c) Fulltext Index is not involved.
6025 d) No GROUP-BY or DISTINCT clause.
6026 e) No ORDER-BY clause.
6027
6028 F2) Not applicable to multi-table query.
6029
6030 F3) This optimization is not applicable to EXPLAIN queries.
6031
6032 @param tab JOIN_TAB object.
6033 @param thd THD object.
6034 */
6035 556993 static bool check_skip_records_in_range_qualification(JOIN_TAB *tab, THD *thd) {
6036 556993 Query_block *select = thd->lex->current_query_block();
6037 556993 TABLE *table = tab->table();
6038
2/2
✓ Branch 0 taken 125178 times.
✓ Branch 1 taken 112 times.
125290 return ((table->force_index &&
6039
2/2
✓ Branch 0 taken 125172 times.
✓ Branch 1 taken 6 times.
250468 table->keys_in_use_for_query.bits_set() == 1) && // F1.a
6040 125178 select->parent_lex->is_single_level_stmt() && // F1.b
6041
2/2
✓ Branch 0 taken 125171 times.
✓ Branch 1 taken 1 times.
125172 !select->has_ft_funcs() && // F1.c
6042
4/4
✓ Branch 0 taken 3537 times.
✓ Branch 1 taken 121634 times.
✓ Branch 2 taken 3531 times.
✓ Branch 3 taken 6 times.
125171 (!select->is_grouped() && !select->is_distinct()) && // F1.d
6043
4/4
✓ Branch 0 taken 2125 times.
✓ Branch 1 taken 1406 times.
✓ Branch 2 taken 2087 times.
✓ Branch 3 taken 38 times.
5656 !select->is_ordered() && // F1.e
6044
2/2
✓ Branch 0 taken 125290 times.
✓ Branch 1 taken 431703 times.
684408 select->join_list->size() == 1 && // F2
6045
2/2
✓ Branch 0 taken 1941 times.
✓ Branch 1 taken 146 times.
559080 !thd->lex->is_explain()); // F3
6046 }
6047
6048 /*****************************************************************************
6049 Create JOIN_TABS, make a guess about the table types,
6050 Approximate how many records will be used in each table
6051 *****************************************************************************/
6052
6053 /**
6054 Returns estimated number of rows that could be fetched by given
6055 access method.
6056
6057 The function calls the range optimizer to estimate the cost of the
6058 cheapest QUICK_* index access method to scan one or several of the
6059 'keys' using the conditions 'select->cond'. The range optimizer
6060 compares several different types of 'quick select' methods (range
6061 scan, index merge, loose index scan) and selects the cheapest one.
6062
6063 If the best index access method is cheaper than a table- and an index
6064 scan, then the range optimizer also constructs the corresponding
6065 QUICK_* object and assigns it to select->quick. In most cases this
6066 is the QUICK_* object used at later (optimization and execution)
6067 phases.
6068
6069 @param thd Session that runs the query.
6070 @param tab JOIN_TAB of source table.
6071 @param limit maximum number of rows to select.
6072
6073 @note
6074 In case of valid range, a RowIterator object will be constructed and
6075 saved in select->quick.
6076
6077 @return Estimated number of result rows selected from 'tab'.
6078
6079 @retval HA_POS_ERROR For derived tables/views or if an error occur.
6080 @retval 0 If impossible query (i.e. certainly no rows will be
6081 selected.)
6082 */
6083 556993 static ha_rows get_quick_record_count(THD *thd, JOIN_TAB *tab, ha_rows limit) {
6084
1/2
✓ Branch 0 taken 556993 times.
✗ Branch 1 not taken.
556993 DBUG_TRACE;
6085 uchar buff[STACK_BUFF_ALLOC];
6086
2/4
✓ Branch 0 taken 556993 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 556993 times.
556993 if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
6087 return 0; // Fatal error flag is set
6088 556993 TABLE_LIST *const tl = tab->table_ref;
6089 1113986 tab->set_skip_records_in_range(
6090
1/2
✓ Branch 0 taken 556993 times.
✗ Branch 1 not taken.
556993 check_skip_records_in_range_qualification(tab, thd));
6091
6092 // Derived tables aren't filled yet, so no stats are available.
6093
2/2
✓ Branch 0 taken 556622 times.
✓ Branch 1 taken 371 times.
556993 if (!tl->uses_materialization()) {
6094 AccessPath *range_scan;
6095 556622 Key_map keys_to_use = tab->const_keys;
6096 556622 keys_to_use.merge(tab->skip_scan_keys);
6097 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
6098 556622 thd->variables.range_alloc_block_size);
6099
3/4
✓ Branch 0 taken 89543 times.
✓ Branch 1 taken 467079 times.
✓ Branch 2 taken 556622 times.
✗ Branch 3 not taken.
1580323 int error = test_quick_select(
6100 thd, thd->mem_root, &temp_mem_root, keys_to_use, 0,
6101 0, // empty table_map
6102 limit,
6103 false, // don't force quick range
6104 556622 ORDER_NOT_RELEVANT, tab->table(), tab->skip_records_in_range(),
6105 556622 tab->join_cond() ? tab->join_cond() : tab->join()->where_cond,
6106 556622 &tab->needed_reg, tab->table()->force_index, tab->join()->query_block,
6107 &range_scan);
6108 556622 tab->set_range_scan(range_scan);
6109
6110
2/2
✓ Branch 0 taken 249371 times.
✓ Branch 1 taken 307251 times.
556622 if (error == 1) return range_scan->num_output_rows;
6111
2/2
✓ Branch 0 taken 1095 times.
✓ Branch 1 taken 306156 times.
307251 if (error == -1) {
6112 1095 tl->table->reginfo.impossible_range = true;
6113 1095 return 0;
6114 }
6115
5/8
✓ Branch 0 taken 306156 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 306156 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 306151 times.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
306156 DBUG_PRINT("warning", ("Couldn't use record count on const keypart"));
6116
8/10
✓ Branch 0 taken 306156 times.
✓ Branch 1 taken 250466 times.
✓ Branch 2 taken 353 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 353 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 353 times.
✓ Branch 8 taken 18 times.
✓ Branch 9 taken 353 times.
556993 } else if (tl->is_table_function() || tl->materializable_is_const()) {
6117
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 tl->fetch_number_of_rows();
6118 18 return tl->table->file->stats.records;
6119 }
6120 306509 return HA_POS_ERROR;
6121 556993 }
6122
6123 /*
6124 Get estimated record length for semi-join materialization temptable
6125
6126 SYNOPSIS
6127 get_tmp_table_rec_length()
6128 items IN subquery's select list.
6129
6130 DESCRIPTION
6131 Calculate estimated record length for semi-join materialization
6132 temptable. It's an estimate because we don't follow every bit of
6133 create_tmp_table()'s logic. This isn't necessary as the return value of
6134 this function is used only for cost calculations.
6135
6136 RETURN
6137 Length of the temptable record, in bytes
6138 */
6139
6140 2635 static uint get_tmp_table_rec_length(const mem_root_deque<Item *> &items) {
6141 2635 uint len = 0;
6142
8/14
✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2635 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2635 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2706 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2706 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5341 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2706 times.
✓ Branch 13 taken 2635 times.
5341 for (Item *item : VisibleFields(items)) {
6143
5/7
✓ Branch 0 taken 2706 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 63 times.
✓ Branch 3 taken 1544 times.
✓ Branch 4 taken 1094 times.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
2706 switch (item->result_type()) {
6144 63 case REAL_RESULT:
6145 63 len += sizeof(double);
6146 63 break;
6147 1544 case INT_RESULT:
6148
2/2
✓ Branch 0 taken 1504 times.
✓ Branch 1 taken 40 times.
1544 if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
6149 1504 len += 8;
6150 else
6151 40 len += 4;
6152 1544 break;
6153 1094 case STRING_RESULT:
6154 /* DATE/TIME and GEOMETRY fields have STRING_RESULT result type. */
6155
5/6
✓ Branch 0 taken 1058 times.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1058 times.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 1058 times.
1094 if (item->is_temporal() || item->data_type() == MYSQL_TYPE_GEOMETRY)
6156 36 len += 8;
6157 else
6158 1058 len += item->max_length;
6159 1094 break;
6160 5 case DECIMAL_RESULT:
6161 5 len += 10;
6162 5 break;
6163 case ROW_RESULT:
6164 default:
6165 assert(0); /* purecov: deadcode */
6166 break;
6167 }
6168 }
6169 2635 return len;
6170 }
6171
6172 /**
6173 Writes to the optimizer trace information about dependencies between
6174 tables.
6175 @param trace optimizer trace
6176 @param join_tabs all JOIN_TABs of the join
6177 @param table_count how many JOIN_TABs in the 'join_tabs' array
6178 */
6179 2702 static void trace_table_dependencies(Opt_trace_context *trace,
6180 JOIN_TAB *join_tabs, uint table_count) {
6181
1/2
✓ Branch 0 taken 2702 times.
✗ Branch 1 not taken.
2702 Opt_trace_object trace_wrapper(trace);
6182
1/2
✓ Branch 0 taken 2702 times.
✗ Branch 1 not taken.
2702 Opt_trace_array trace_dep(trace, "table_dependencies");
6183
2/2
✓ Branch 0 taken 3197 times.
✓ Branch 1 taken 2702 times.
5899 for (uint i = 0; i < table_count; i++) {
6184 3197 TABLE_LIST *table_ref = join_tabs[i].table_ref;
6185
1/2
✓ Branch 0 taken 3197 times.
✗ Branch 1 not taken.
3197 Opt_trace_object trace_one_table(trace);
6186
2/4
✓ Branch 0 taken 3197 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3197 times.
✗ Branch 3 not taken.
6394 trace_one_table.add_utf8_table(table_ref).add(
6187 3197 "row_may_be_null", table_ref->table->is_nullable());
6188 3197 const table_map map = table_ref->map();
6189
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3197 times.
3197 assert(map < (1ULL << table_count));
6190
1/2
✓ Branch 0 taken 3955 times.
✗ Branch 1 not taken.
3955 for (uint j = 0; j < table_count; j++) {
6191
2/2
✓ Branch 0 taken 3197 times.
✓ Branch 1 taken 758 times.
3955 if (map & (1ULL << j)) {
6192
1/2
✓ Branch 0 taken 3197 times.
✗ Branch 1 not taken.
3197 trace_one_table.add("map_bit", j);
6193 3197 break;
6194 }
6195 }
6196
1/2
✓ Branch 0 taken 3197 times.
✗ Branch 1 not taken.
3197 Opt_trace_array depends_on(trace, "depends_on_map_bits");
6197 static_assert(sizeof(table_ref->map()) <= 64,
6198 "RAND_TABLE_BIT may be in join_tabs[i].dependent, so we test "
6199 "all 64 bits.");
6200
2/2
✓ Branch 0 taken 204608 times.
✓ Branch 1 taken 3197 times.
207805 for (uint j = 0; j < 64; j++) {
6201
3/4
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 204308 times.
✓ Branch 2 taken 300 times.
✗ Branch 3 not taken.
204608 if (join_tabs[i].dependent & (1ULL << j)) depends_on.add(j);
6202 }
6203 3197 }
6204 2702 }
6205
6206 /**
6207 Add to join_tab[i]->condition() "table.field IS NOT NULL" conditions
6208 we've inferred from ref/eq_ref access performed.
6209
6210 This function is a part of "Early NULL-values filtering for ref access"
6211 optimization.
6212
6213 Example of this optimization:
6214 For query SELECT * FROM t1,t2 WHERE t2.key=t1.field @n
6215 and plan " any-access(t1), ref(t2.key=t1.field) " @n
6216 add "t1.field IS NOT NULL" to t1's table condition. @n
6217
6218 Description of the optimization:
6219
6220 We look through equalities chosen to perform ref/eq_ref access,
6221 pick equalities that have form "tbl.part_of_key = othertbl.field"
6222 (where othertbl is a non-const table and othertbl.field may be NULL)
6223 and add them to conditions on corresponding tables (othertbl in this
6224 example).
6225
6226 Exception from that is the case when referred_tab->join != join.
6227 I.e. don't add NOT NULL constraints from any embedded subquery.
6228 Consider this query:
6229 @code
6230 SELECT A.f2 FROM t1 LEFT JOIN t2 A ON A.f2 = f1
6231 WHERE A.f3=(SELECT MIN(f3) FROM t2 C WHERE A.f4 = C.f4) OR A.f3 IS NULL;
6232 @endcode
6233 Here condition A.f3 IS NOT NULL is going to be added to the WHERE
6234 condition of the embedding query.
6235 Another example:
6236 SELECT * FROM t10, t11 WHERE (t10.a < 10 OR t10.a IS NULL)
6237 AND t11.b <=> t10.b AND (t11.a = (SELECT MAX(a) FROM t12
6238 WHERE t12.b = t10.a ));
6239 Here condition t10.a IS NOT NULL is going to be added.
6240 In both cases addition of NOT NULL condition will erroneously reject
6241 some rows of the result set.
6242 referred_tab->join != join constraint would disallow such additions.
6243
6244 This optimization doesn't affect the choices that ref, range, or join
6245 optimizer make. This was intentional because this was added after 4.1
6246 was GA.
6247
6248 Implementation overview
6249 1. update_ref_and_keys() accumulates info about null-rejecting
6250 predicates in in Key_field::null_rejecting
6251 1.1 add_key_part saves these to Key_use.
6252 2. create_ref_for_key copies them to TABLE_REF.
6253 3. add_not_null_conds adds "x IS NOT NULL" to join_tab->m_condition of
6254 appropriate JOIN_TAB members.
6255
6256 @returns false on success, true on error
6257 */
6258
6259 1903440 static bool add_not_null_conds(JOIN *join) {
6260
1/2
✓ Branch 0 taken 1903459 times.
✗ Branch 1 not taken.
1903440 DBUG_TRACE;
6261
4/6
✓ Branch 0 taken 1903459 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1903458 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1903458 times.
✗ Branch 5 not taken.
1903459 ASSERT_BEST_REF_IN_JOIN_ORDER(join);
6262
2/2
✓ Branch 0 taken 6384959 times.
✓ Branch 1 taken 1903477 times.
8288436 for (uint i = join->const_tables; i < join->tables; i++) {
6263 6384959 JOIN_TAB *const tab = join->best_ref[i];
6264
4/4
✓ Branch 0 taken 4369119 times.
✓ Branch 1 taken 1544344 times.
✓ Branch 2 taken 128 times.
✓ Branch 3 taken 4368990 times.
16667535 if ((tab->type() != JT_REF && tab->type() != JT_EQ_REF &&
6265
6/6
✓ Branch 0 taken 5913458 times.
✓ Branch 1 taken 471508 times.
✓ Branch 2 taken 394830 times.
✓ Branch 3 taken 1621158 times.
✓ Branch 4 taken 4763821 times.
✓ Branch 5 taken 1621157 times.
17139063 tab->type() != JT_REF_OR_NULL) ||
6266 2015980 tab->table()->is_nullable()) {
6267 4763821 continue;
6268 }
6269
2/2
✓ Branch 0 taken 2133923 times.
✓ Branch 1 taken 1621157 times.
3755088 for (uint keypart = 0; keypart < tab->ref().key_parts; keypart++) {
6270
2/2
✓ Branch 0 taken 1822027 times.
✓ Branch 1 taken 311902 times.
2133923 if ((tab->ref().null_rejecting & ((key_part_map)1 << keypart)) == 0) {
6271 1971175 continue;
6272 }
6273
1/2
✓ Branch 0 taken 311904 times.
✗ Branch 1 not taken.
311902 Item *const item = tab->ref().items[keypart]->real_item();
6274
7/8
✓ Branch 0 taken 311904 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 173215 times.
✓ Branch 3 taken 138689 times.
✓ Branch 4 taken 524 times.
✓ Branch 5 taken 172691 times.
✓ Branch 6 taken 139213 times.
✓ Branch 7 taken 172691 times.
311904 if (item->type() != Item::FIELD_ITEM || !item->is_nullable()) continue;
6275 172691 Item_field *const not_null_item = down_cast<Item_field *>(item);
6276 172691 JOIN_TAB *referred_tab = not_null_item->field->table->reginfo.join_tab;
6277 /*
6278 For UPDATE queries such as:
6279 UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
6280 not_null_item is the t1.f1, but it's referred_tab is 0.
6281 */
6282
5/6
✓ Branch 0 taken 172604 times.
✓ Branch 1 taken 87 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 172604 times.
✓ Branch 4 taken 87 times.
✓ Branch 5 taken 172604 times.
172691 if (referred_tab == nullptr || referred_tab->join() != join) continue;
6283 /* Skip if we already have a 'not null' predicate for 'item' */
6284
3/4
✓ Branch 0 taken 172604 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9848 times.
✓ Branch 3 taken 162756 times.
172604 if (has_not_null_predicate(referred_tab->condition(), not_null_item))
6285 9848 continue;
6286
2/4
✓ Branch 0 taken 162756 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 162756 times.
✗ Branch 3 not taken.
162756 Item *notnull = new Item_func_isnotnull(not_null_item);
6287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 162756 times.
162756 if (notnull == nullptr) return true;
6288 /*
6289 We need to do full fix_fields() call here in order to have correct
6290 notnull->const_item(). This is needed e.g. by test_quick_select
6291 when it is called from make_join_query_block after this function is
6292 called.
6293 */
6294
2/4
✓ Branch 0 taken 162756 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 162756 times.
162756 if (notnull->fix_fields(join->thd, &notnull)) return true;
6295
2/6
✓ Branch 0 taken 162756 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 162756 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
162756 DBUG_EXECUTE("where",
6296 print_where(join->thd, notnull, referred_tab->table()->alias,
6297 QT_ORDINARY););
6298
1/2
✓ Branch 0 taken 162756 times.
✗ Branch 1 not taken.
162756 referred_tab->and_with_condition(notnull);
6299 }
6300 }
6301 1903477 return false;
6302 1903477 }
6303
6304 /**
6305 Check all existing AND'ed predicates in 'cond' for an existing
6306 'is not null 'not_null_item''-predicate.
6307
6308 A condition consisting of multiple AND'ed terms is recursively
6309 decomposed in the search for the specified not null predicate.
6310
6311 @param cond Condition to be checked.
6312 @param not_null_item The item in: 'is not null 'item'' to search for
6313
6314 @return true if 'is not null 'not_null_item'' is a predicate
6315 in the specified 'cond'.
6316 */
6317 172948 static bool has_not_null_predicate(Item *cond, Item_field *not_null_item) {
6318
2/2
✓ Branch 0 taken 131943 times.
✓ Branch 1 taken 41005 times.
172948 if (cond == nullptr) return false;
6319
2/2
✓ Branch 0 taken 40831 times.
✓ Branch 1 taken 174 times.
41005 if (cond->type() == Item::FUNC_ITEM) {
6320 40831 Item_func *item_func = down_cast<Item_func *>(cond);
6321 40831 const Item_func::Functype func_type = item_func->functype();
6322
1/2
✓ Branch 0 taken 40831 times.
✗ Branch 1 not taken.
81662 return (func_type == Item_func::ISNOTNULL_FUNC &&
6323
2/2
✓ Branch 0 taken 9848 times.
✓ Branch 1 taken 30983 times.
81662 item_func->key_item() == not_null_item);
6324
1/2
✓ Branch 0 taken 174 times.
✗ Branch 1 not taken.
174 } else if (cond->type() == Item::COND_ITEM) {
6325 174 Item_cond *item_cond = down_cast<Item_cond *>(cond);
6326
1/2
✓ Branch 0 taken 174 times.
✗ Branch 1 not taken.
174 if (item_cond->functype() == Item_func::COND_AND_FUNC) {
6327
1/2
✓ Branch 0 taken 174 times.
✗ Branch 1 not taken.
174 List_iterator<Item> li(*item_cond->argument_list());
6328 Item *item;
6329
2/2
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 166 times.
510 while ((item = li++)) {
6330
3/4
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 336 times.
344 if (has_not_null_predicate(item, not_null_item)) return true;
6331 }
6332 }
6333 }
6334 166 return false;
6335 }
6336
6337 /**
6338 Check if given expression only uses fields covered by index @a keyno in the
6339 table tbl. The expression can use any fields in any other tables.
6340
6341 The expression is guaranteed not to be AND or OR - those constructs are
6342 handled outside of this function.
6343
6344 Restrict some function types from being pushed down to storage engine:
6345 a) Don't push down the triggered conditions. Nested outer joins execution
6346 code may need to evaluate a condition several times (both triggered and
6347 untriggered).
6348 TODO: Consider cloning the triggered condition and using the copies for:
6349 1. push the first copy down, to have most restrictive index condition
6350 possible.
6351 2. Put the second copy into tab->m_condition.
6352 b) Stored functions contain a statement that might start new operations (like
6353 DML statements) from within the storage engine. This does not work against
6354 all SEs.
6355 c) Subqueries might contain nested subqueries and involve more tables.
6356 TODO: ROY: CHECK THIS
6357 d) Do not push down internal functions of type DD_INTERNAL_FUNC. When ICP is
6358 enabled, pushing internal functions to storage engine for evaluation will
6359 open data-dictionary tables. In InnoDB storage engine this will result in
6360 situation like recursive latching of same page by the same thread. To avoid
6361 such situation, internal functions of type DD_INTERNAL_FUNC are not pushed
6362 to storage engine for evaluation.
6363
6364 @param item Expression to check
6365 @param tbl The table having the index
6366 @param keyno The index number
6367 @param other_tbls_ok true <=> Fields of other non-const tables are allowed
6368
6369 @return false if No, true if Yes
6370 */
6371
6372 22365 bool uses_index_fields_only(Item *item, TABLE *tbl, uint keyno,
6373 bool other_tbls_ok) {
6374 // Restrictions b and c.
6375
6/6
✓ Branch 0 taken 22355 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 55 times.
✓ Branch 3 taken 22300 times.
✓ Branch 4 taken 65 times.
✓ Branch 5 taken 22300 times.
22365 if (item->has_stored_program() || item->has_subquery()) return false;
6376
6377 // No table fields in const items
6378
2/2
✓ Branch 0 taken 5748 times.
✓ Branch 1 taken 16552 times.
22300 if (item->const_for_execution()) return true;
6379
6380 16552 const Item::Type item_type = item->type();
6381
6382
4/5
✓ Branch 0 taken 8371 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8116 times.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 32 times.
16552 switch (item_type) {
6383 8371 case Item::FUNC_ITEM: {
6384 8371 Item_func *item_func = (Item_func *)item;
6385 8371 const Item_func::Functype func_type = item_func->functype();
6386
6387
3/4
✓ Branch 0 taken 8236 times.
✓ Branch 1 taken 135 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8236 times.
8371 if (func_type == Item_func::TRIG_COND_FUNC || // Restriction a.
6388 func_type == Item_func::DD_INTERNAL_FUNC) // Restriction d.
6389 135 return false;
6390
6391 /* This is a function, apply condition recursively to arguments */
6392
2/2
✓ Branch 0 taken 8232 times.
✓ Branch 1 taken 4 times.
8236 if (item_func->argument_count() > 0) {
6393 Item **item_end =
6394 8232 (item_func->arguments()) + item_func->argument_count();
6395
2/2
✓ Branch 0 taken 14196 times.
✓ Branch 1 taken 5808 times.
20004 for (Item **child = item_func->arguments(); child != item_end;
6396 child++) {
6397
2/2
✓ Branch 0 taken 2424 times.
✓ Branch 1 taken 11772 times.
14196 if (!uses_index_fields_only(*child, tbl, keyno, other_tbls_ok))
6398 2424 return false;
6399 }
6400 }
6401 5812 return true;
6402 }
6403 case Item::COND_ITEM: {
6404 /*
6405 This is a AND/OR condition. Regular AND/OR clauses are handled by
6406 make_cond_for_index() which will chop off the part that can be
6407 checked with index. This code is for handling non-top-level AND/ORs,
6408 e.g. func(x AND y).
6409 */
6410 List_iterator<Item> li(*((Item_cond *)item)->argument_list());
6411 Item *cond_item;
6412 while ((cond_item = li++)) {
6413 if (!uses_index_fields_only(cond_item, tbl, keyno, other_tbls_ok))
6414 return false;
6415 }
6416 return true;
6417 }
6418 8116 case Item::FIELD_ITEM: {
6419 8116 const Item_field *item_field = down_cast<const Item_field *>(item);
6420
2/2
✓ Branch 0 taken 197 times.
✓ Branch 1 taken 7919 times.
8116 if (item_field->field->table != tbl) return other_tbls_ok;
6421 /*
6422 The below is probably a repetition - the first part checks the
6423 other two, but let's play it safe:
6424 */
6425 7919 return item_field->field->part_of_key.is_set(keyno) &&
6426
3/4
✓ Branch 0 taken 5576 times.
✓ Branch 1 taken 2343 times.
✓ Branch 2 taken 5576 times.
✗ Branch 3 not taken.
13495 item_field->field->type() != MYSQL_TYPE_GEOMETRY &&
6427
1/2
✓ Branch 0 taken 5576 times.
✗ Branch 1 not taken.
13495 item_field->field->type() != MYSQL_TYPE_BLOB;
6428 }
6429 33 case Item::REF_ITEM:
6430 33 return uses_index_fields_only(item->real_item(), tbl, keyno,
6431 33 other_tbls_ok);
6432 32 default:
6433 32 return false; /* Play it safe, don't push unknown non-const items */
6434 }
6435 }
6436
6437 /**
6438 Optimize semi-join nests that could be run with sj-materialization
6439
6440 @param join The join to optimize semi-join nests for
6441
6442 @details
6443 Optimize each of the semi-join nests that can be run with
6444 materialization. For each of the nests, we
6445 - Generate the best join order for this "sub-join" and remember it;
6446 - Remember the sub-join execution cost (it's part of materialization
6447 cost);
6448 - Calculate other costs that will be incurred if we decide
6449 to use materialization strategy for this semi-join nest.
6450
6451 All obtained information is saved and will be used by the main join
6452 optimization pass.
6453
6454 @return false if successful, true if error
6455 */
6456
6457 2961 static bool optimize_semijoin_nests_for_materialization(JOIN *join) {
6458
1/2
✓ Branch 0 taken 2961 times.
✗ Branch 1 not taken.
2961 DBUG_TRACE;
6459 2961 Opt_trace_context *const trace = &join->thd->opt_trace;
6460
6461
7/12
✓ Branch 0 taken 2961 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2961 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2798 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2798 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5759 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2798 times.
✓ Branch 11 taken 2961 times.
5759 for (TABLE_LIST *sj_nest : join->query_block->sj_nests) {
6462 /* As a precaution, reset pointers that were used in prior execution */
6463 2798 sj_nest->nested_join->sjm.positions = nullptr;
6464
6465 /* Calculate the cost of materialization if materialization is allowed. */
6466
2/2
✓ Branch 0 taken 2656 times.
✓ Branch 1 taken 142 times.
2798 if (sj_nest->nested_join->sj_enabled_strategies &
6467 OPTIMIZER_SWITCH_MATERIALIZATION) {
6468 /* A semi-join nest should not contain tables marked as const */
6469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2656 times.
2656 assert(!(sj_nest->sj_inner_tables & join->const_table_map));
6470
6471
1/2
✓ Branch 0 taken 2656 times.
✗ Branch 1 not taken.
2656 Opt_trace_object trace_wrapper(trace);
6472 Opt_trace_object trace_sjmat(
6473
1/2
✓ Branch 0 taken 2656 times.
✗ Branch 1 not taken.
2656 trace, "execution_plan_for_potential_materialization");
6474
1/2
✓ Branch 0 taken 2656 times.
✗ Branch 1 not taken.
2656 Opt_trace_array trace_sjmat_steps(trace, "steps");
6475 /*
6476 Try semijoin materialization if the semijoin is classified as
6477 non-trivially-correlated.
6478 */
6479
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 2576 times.
2656 if (sj_nest->nested_join->sj_corr_tables) continue;
6480 /*
6481 Check whether data types allow execution with materialization.
6482 */
6483
1/2
✓ Branch 0 taken 2576 times.
✗ Branch 1 not taken.
2576 semijoin_types_allow_materialization(sj_nest);
6484
6485
2/2
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 2333 times.
2576 if (!sj_nest->nested_join->sjm.scan_allowed &&
6486
1/2
✓ Branch 0 taken 243 times.
✗ Branch 1 not taken.
243 !sj_nest->nested_join->sjm.lookup_allowed)
6487 243 continue;
6488
6489
3/6
✓ Branch 0 taken 2333 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2333 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2333 times.
2333 if (Optimize_table_order(join->thd, join, sj_nest).choose_table_order())
6490 return true;
6491 2333 const uint n_tables = my_count_bits(sj_nest->sj_inner_tables);
6492 2333 calculate_materialization_costs(join, sj_nest, n_tables,
6493
1/2
✓ Branch 0 taken 2333 times.
✗ Branch 1 not taken.
2333 &sj_nest->nested_join->sjm);
6494 /*
6495 Cost data is in sj_nest->nested_join->sjm. We also need to save the
6496 plan:
6497 */
6498 4666 if (!(sj_nest->nested_join->sjm.positions =
6499
2/4
✓ Branch 0 taken 2333 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2333 times.
2333 (POSITION *)join->thd->alloc(sizeof(POSITION) * n_tables)))
6500 return true;
6501 2333 memcpy(sj_nest->nested_join->sjm.positions,
6502 2333 join->best_positions + join->const_tables,
6503 2333 sizeof(POSITION) * n_tables);
6504
6/9
✓ Branch 0 taken 2333 times.
✓ Branch 1 taken 323 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2333 times.
✓ Branch 4 taken 323 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2333 times.
✓ Branch 7 taken 323 times.
✗ Branch 8 not taken.
3302 }
6505 }
6506 2961 return false;
6507 2961 }
6508
6509 /*
6510 Check if table's Key_use elements have an eq_ref(outer_tables) candidate
6511
6512 SYNOPSIS
6513 find_eq_ref_candidate()
6514 tl Table to be checked
6515 sj_inner_tables Bitmap of inner tables. eq_ref(inner_table) doesn't
6516 count.
6517
6518 DESCRIPTION
6519 Check if table's Key_use elements have an eq_ref(outer_tables) candidate
6520
6521 TODO
6522 Check again if it is feasible to factor common parts with constant table
6523 search
6524
6525 RETURN
6526 true - There exists an eq_ref(outer-tables) candidate
6527 false - Otherwise
6528 */
6529
6530 6645 static bool find_eq_ref_candidate(TABLE_LIST *tl, table_map sj_inner_tables) {
6531 6645 Key_use *keyuse = tl->table->reginfo.join_tab->keyuse();
6532
6533
2/2
✓ Branch 0 taken 5330 times.
✓ Branch 1 taken 1315 times.
6645 if (keyuse) {
6534 while (true) /* For each key */
6535 {
6536 7080 const uint key = keyuse->key;
6537 7080 KEY *const keyinfo = tl->table->key_info + key;
6538 7080 key_part_map bound_parts = 0;
6539
2/2
✓ Branch 0 taken 6488 times.
✓ Branch 1 taken 592 times.
7080 if ((keyinfo->flags & (HA_NOSAME)) == HA_NOSAME) {
6540 do /* For all equalities on all key parts */
6541 {
6542 /* Check if this is "t.keypart = expr(outer_tables) */
6543
2/2
✓ Branch 0 taken 2732 times.
✓ Branch 1 taken 5323 times.
8055 if (!(keyuse->used_tables & sj_inner_tables) &&
6544
1/2
✓ Branch 0 taken 2732 times.
✗ Branch 1 not taken.
2732 !(keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)) {
6545 /*
6546 Consider only if the resulting condition does not pass a NULL
6547 value through. Especially needed for a UNIQUE index on NULLable
6548 columns where a duplicate row is possible with NULL values.
6549 */
6550
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2732 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2732 times.
✗ Branch 5 not taken.
2732 if (keyuse->null_rejecting || !keyuse->val->is_nullable() ||
6551 !keyinfo->key_part[keyuse->keypart].field->is_nullable())
6552 2732 bound_parts |= (key_part_map)1 << keyuse->keypart;
6553 }
6554 8055 keyuse++;
6555
4/4
✓ Branch 0 taken 3617 times.
✓ Branch 1 taken 4438 times.
✓ Branch 2 taken 1567 times.
✓ Branch 3 taken 2050 times.
8055 } while (keyuse->key == key && keyuse->table_ref == tl);
6556
6557
2/2
✓ Branch 0 taken 1796 times.
✓ Branch 1 taken 4692 times.
6488 if (bound_parts == LOWER_BITS(uint, keyinfo->user_defined_key_parts))
6558 1796 return true;
6559
2/2
✓ Branch 0 taken 3021 times.
✓ Branch 1 taken 1671 times.
4692 if (keyuse->table_ref != tl) return false;
6560 } else {
6561 do {
6562 791 keyuse++;
6563
2/2
✓ Branch 0 taken 513 times.
✓ Branch 1 taken 278 times.
791 if (keyuse->table_ref != tl) return false;
6564
2/2
✓ Branch 0 taken 199 times.
✓ Branch 1 taken 79 times.
278 } while (keyuse->key == key);
6565 }
6566 1750 }
6567 }
6568 1315 return false;
6569 }
6570
6571 /**
6572 Pull tables out of semi-join nests based on functional dependencies
6573
6574 @param join The join where to do the semi-join table pullout
6575
6576 @return False if successful, true if error (Out of memory)
6577
6578 @details
6579 Pull tables out of semi-join nests based on functional dependencies,
6580 ie. if a table is accessed via eq_ref(outer_tables).
6581 The function may be called several times, the caller is responsible
6582 for setting up proper key information that this function acts upon.
6583
6584 PRECONDITIONS
6585 When this function is called, the join may have several semi-join nests
6586 but it is guaranteed that one semi-join nest does not contain another.
6587 For functionally dependent tables to be pulled out, key information must
6588 have been calculated (see update_ref_and_keys()).
6589
6590 POSTCONDITIONS
6591 * Tables that were pulled out are removed from the semi-join nest they
6592 belonged to and added to the parent join nest.
6593 * For these tables, the used_tables and not_null_tables fields of
6594 the semi-join nest they belonged to will be adjusted.
6595 The semi-join nest is also marked as correlated, and
6596 sj_corr_tables and sj_depends_on are adjusted if necessary.
6597 * Semi-join nests' sj_inner_tables is set equal to used_tables
6598
6599 NOTE
6600 Table pullout may make uncorrelated subquery correlated. Consider this
6601 example:
6602
6603 ... WHERE oe IN (SELECT it1.primary_key WHERE p(it1, it2) ... )
6604
6605 here table it1 can be pulled out (we have it1.primary_key=oe which gives
6606 us functional dependency). Once it1 is pulled out, all references to it1
6607 from p(it1, it2) become references to outside of the subquery and thus
6608 make the subquery (i.e. its semi-join nest) correlated.
6609 Making the subquery (i.e. its semi-join nest) correlated prevents us from
6610 using Materialization or LooseScan to execute it.
6611 */
6612
6613 4435 static bool pull_out_semijoin_tables(JOIN *join) {
6614
1/2
✓ Branch 0 taken 4435 times.
✗ Branch 1 not taken.
4435 DBUG_TRACE;
6615
6616
2/4
✓ Branch 0 taken 4435 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4435 times.
4435 assert(!join->query_block->sj_nests.empty());
6617
6618 4435 Opt_trace_context *const trace = &join->thd->opt_trace;
6619
1/2
✓ Branch 0 taken 4435 times.
✗ Branch 1 not taken.
4435 Opt_trace_object trace_wrapper(trace);
6620
1/2
✓ Branch 0 taken 4435 times.
✗ Branch 1 not taken.
4435 Opt_trace_array trace_pullout(trace, "pulled_out_semijoin_tables");
6621
6622 /* Try pulling out tables from each semi-join nest */
6623
1/2
✓ Branch 0 taken 4435 times.
✗ Branch 1 not taken.
4435 for (auto sj_list_it = join->query_block->sj_nests.begin();
6624
4/6
✓ Branch 0 taken 8980 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8980 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4545 times.
✓ Branch 5 taken 4435 times.
8980 sj_list_it != join->query_block->sj_nests.end();) {
6625
1/2
✓ Branch 0 taken 4545 times.
✗ Branch 1 not taken.
4545 TABLE_LIST *sj_nest = *sj_list_it;
6626
2/2
✓ Branch 0 taken 182 times.
✓ Branch 1 taken 4363 times.
4545 if (sj_nest->is_aj_nest()) {
6627
1/2
✓ Branch 0 taken 182 times.
✗ Branch 1 not taken.
182 ++sj_list_it;
6628 182 continue;
6629 }
6630 4363 table_map pulled_tables = 0;
6631 /*
6632 Calculate set of tables within this semi-join nest that have
6633 other dependent tables. They cannot be pulled out. For example, with
6634 t1 SEMIJOIN (t2 LEFT JOIN t3 ON ...) ON t1.a=t2.pk,
6635 t2 cannot be pulled out because t3 depends on it.
6636 */
6637 4363 table_map dep_tables = 0;
6638
7/12
✓ Branch 0 taken 4363 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4363 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11962 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11962 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 16325 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 11962 times.
✓ Branch 11 taken 4363 times.
16325 for (TABLE_LIST *tbl : sj_nest->nested_join->join_list) {
6639
2/2
✓ Branch 0 taken 3786 times.
✓ Branch 1 taken 8176 times.
11962 if (tbl->dep_tables & sj_nest->nested_join->used_tables)
6640 3786 dep_tables |= tbl->dep_tables;
6641 }
6642 /*
6643 Find which tables we can pull out based on key dependency data.
6644 Note that pulling one table out can allow us to pull out some
6645 other tables too.
6646 */
6647 bool pulled_a_table;
6648
2/2
✓ Branch 0 taken 1793 times.
✓ Branch 1 taken 4363 times.
6156 do {
6649 6156 pulled_a_table = false;
6650
7/12
✓ Branch 0 taken 6156 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6156 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13775 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13775 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 19931 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 13775 times.
✓ Branch 11 taken 6156 times.
19931 for (TABLE_LIST *tbl : sj_nest->nested_join->join_list) {
6651
6/6
✓ Branch 0 taken 13774 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 11971 times.
✓ Branch 3 taken 1803 times.
✓ Branch 4 taken 6645 times.
✓ Branch 5 taken 7130 times.
25746 if (tbl->table && !(pulled_tables & tbl->map()) &&
6652
2/2
✓ Branch 0 taken 6645 times.
✓ Branch 1 taken 5326 times.
11971 !(dep_tables & tbl->map())) {
6653
2/2
✓ Branch 0 taken 1796 times.
✓ Branch 1 taken 4849 times.
6645 if (find_eq_ref_candidate(
6654 6645 tbl, sj_nest->nested_join->used_tables & ~pulled_tables)) {
6655 1796 pulled_a_table = true;
6656 1796 pulled_tables |= tbl->map();
6657
3/6
✓ Branch 0 taken 1796 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1796 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1796 times.
✗ Branch 5 not taken.
1796 Opt_trace_object(trace).add_utf8_table(tbl).add(
6658 "functionally_dependent", true);
6659 /*
6660 Pulling a table out of uncorrelated subquery in general makes
6661 it correlated. See the NOTE to this function.
6662 */
6663 1796 sj_nest->nested_join->sj_corr_tables |= tbl->map();
6664 1796 sj_nest->nested_join->sj_depends_on |= tbl->map();
6665 }
6666 }
6667 }
6668 } while (pulled_a_table);
6669
6670 /*
6671 Move the pulled out TABLE_LIST elements to the parents.
6672 */
6673 4363 sj_nest->nested_join->used_tables &= ~pulled_tables;
6674 4363 sj_nest->nested_join->not_null_tables &= ~pulled_tables;
6675
6676 /* sj_inner_tables is a copy of nested_join->used_tables */
6677 4363 sj_nest->sj_inner_tables = sj_nest->nested_join->used_tables;
6678
6679 4363 bool remove = false;
6680
2/2
✓ Branch 0 taken 1786 times.
✓ Branch 1 taken 2577 times.
4363 if (pulled_tables) {
6681 1786 mem_root_deque<TABLE_LIST *> *upper_join_list =
6682 1786 (sj_nest->embedding != nullptr)
6683
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1784 times.
1786 ? &sj_nest->embedding->nested_join->join_list
6684 1784 : &join->query_block->top_join_list;
6685
6686
1/2
✓ Branch 0 taken 1786 times.
✗ Branch 1 not taken.
1786 Prepared_stmt_arena_holder ps_arena_holder(join->thd);
6687
6688
1/2
✓ Branch 0 taken 1786 times.
✗ Branch 1 not taken.
1786 for (auto child_li = sj_nest->nested_join->join_list.begin();
6689
4/6
✓ Branch 0 taken 3585 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3585 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1799 times.
✓ Branch 5 taken 1786 times.
3585 child_li != sj_nest->nested_join->join_list.end();) {
6690
1/2
✓ Branch 0 taken 1799 times.
✗ Branch 1 not taken.
1799 TABLE_LIST *tbl = *child_li;
6691
5/6
✓ Branch 0 taken 1799 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1796 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1796 times.
✓ Branch 5 taken 3 times.
1799 if (tbl->table && !(sj_nest->nested_join->used_tables & tbl->map())) {
6692 /*
6693 Pull the table up in the same way as simplify_joins() does:
6694 update join_list and embedding pointers but keep next[_local]
6695 pointers.
6696 */
6697
1/2
✓ Branch 0 taken 1796 times.
✗ Branch 1 not taken.
1796 child_li = sj_nest->nested_join->join_list.erase(child_li);
6698
6699
1/2
✓ Branch 0 taken 1796 times.
✗ Branch 1 not taken.
1796 upper_join_list->push_back(tbl);
6700
6701 1796 tbl->join_list = upper_join_list;
6702 1796 tbl->embedding = sj_nest->embedding;
6703 } else {
6704
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 ++child_li;
6705 }
6706 }
6707
6708 /* Remove the sj-nest itself if we've removed everything from it */
6709
2/2
✓ Branch 0 taken 1784 times.
✓ Branch 1 taken 2 times.
1786 if (!sj_nest->nested_join->used_tables) {
6710
4/8
✓ Branch 0 taken 1784 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1784 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1784 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1784 times.
✗ Branch 7 not taken.
1784 upper_join_list->erase(std::find(upper_join_list->begin(),
6711 upper_join_list->end(), sj_nest));
6712 /* Also remove it from the list of SJ-nests: */
6713 1784 remove = true;
6714 }
6715 1786 }
6716
6717
2/2
✓ Branch 0 taken 1784 times.
✓ Branch 1 taken 2579 times.
4363 if (remove) {
6718
1/2
✓ Branch 0 taken 1784 times.
✗ Branch 1 not taken.
1784 sj_list_it = join->query_block->sj_nests.erase(sj_list_it);
6719 } else {
6720
1/2
✓ Branch 0 taken 2579 times.
✗ Branch 1 not taken.
2579 ++sj_list_it;
6721 }
6722 }
6723 4435 return false;
6724 4435 }
6725
6726 /* Values in optimize */
6727 #define KEY_OPTIMIZE_EXISTS 1
6728 #define KEY_OPTIMIZE_REF_OR_NULL 2
6729
6730 /**
6731 Merge new key definitions to old ones, remove those not used in both.
6732
6733 This is called for OR between different levels.
6734
6735 To be able to do 'ref_or_null' we merge a comparison of a column
6736 and 'column IS NULL' to one test. This is useful for sub select queries
6737 that are internally transformed to something like:.
6738
6739 @code
6740 SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL
6741 @endcode
6742
6743 Key_field::null_rejecting is processed as follows: @n
6744 result has null_rejecting=true if it is set for both ORed references.
6745 for example:
6746 - (t2.key = t1.field OR t2.key = t1.field) -> null_rejecting=true
6747 - (t2.key = t1.field OR t2.key <=> t1.field) -> null_rejecting=false
6748
6749 @todo
6750 The result of this is that we're missing some 'ref' accesses.
6751 OptimizerTeam: Fix this
6752 */
6753
6754 30252 static Key_field *merge_key_fields(Key_field *start, Key_field *new_fields,
6755 Key_field *end, uint and_level) {
6756
2/2
✓ Branch 0 taken 27269 times.
✓ Branch 1 taken 2983 times.
30252 if (start == new_fields) return start; // Impossible or
6757
2/2
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 2701 times.
2983 if (new_fields == end) return start; // No new fields, skip all
6758
6759 2701 Key_field *first_free = new_fields;
6760
6761 /* Mark all found fields in old array */
6762
2/2
✓ Branch 0 taken 3677 times.
✓ Branch 1 taken 2701 times.
6378 for (; new_fields != end; new_fields++) {
6763 3677 const Field *const new_field = new_fields->item_field->field;
6764
6765
2/2
✓ Branch 0 taken 32479 times.
✓ Branch 1 taken 2024 times.
34503 for (Key_field *old = start; old != first_free; old++) {
6766 32479 const Field *const old_field = old->item_field->field;
6767
6768 /*
6769 Check that the Field objects are the same, as we may have several
6770 Item_field objects pointing to the same Field:
6771 */
6772
2/2
✓ Branch 0 taken 6157 times.
✓ Branch 1 taken 26322 times.
32479 if (old_field == new_field) {
6773 /*
6774 NOTE: below const_item() call really works as "!used_tables()", i.e.
6775 it can return false where it is feasible to make it return true.
6776
6777 The cause is as follows: Some of the tables are already known to be
6778 const tables (the detection code is in JOIN::make_join_plan(),
6779 above the update_ref_and_keys() call), but we didn't propagate
6780 information about this: TABLE::const_table is not set to true, and
6781 Item::update_used_tables() hasn't been called for each item.
6782 The result of this is that we're missing some 'ref' accesses.
6783 TODO: OptimizerTeam: Fix this
6784 */
6785
2/2
✓ Branch 0 taken 3692 times.
✓ Branch 1 taken 2465 times.
6157 if (!new_fields->val->const_item()) {
6786 /*
6787 If the value matches, we can use the key reference.
6788 If not, we keep it until we have examined all new values
6789 */
6790
2/2
✓ Branch 0 taken 534 times.
✓ Branch 1 taken 3158 times.
3692 if (old->val->eq(new_fields->val, old_field->binary())) {
6791 534 old->level = and_level;
6792 534 old->optimize =
6793 534 ((old->optimize & new_fields->optimize & KEY_OPTIMIZE_EXISTS) |
6794 534 ((old->optimize | new_fields->optimize) &
6795 KEY_OPTIMIZE_REF_OR_NULL));
6796 534 old->null_rejecting =
6797
2/4
✓ Branch 0 taken 534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 534 times.
✗ Branch 3 not taken.
534 (old->null_rejecting && new_fields->null_rejecting);
6798 }
6799
4/6
✓ Branch 0 taken 2465 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2465 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 323 times.
✓ Branch 5 taken 2142 times.
4930 } else if (old->eq_func && new_fields->eq_func &&
6800
2/2
✓ Branch 0 taken 323 times.
✓ Branch 1 taken 2142 times.
2465 old->val->eq_by_collation(new_fields->val,
6801 2465 old_field->binary(),
6802 2465 old_field->charset())) {
6803 323 old->level = and_level;
6804 323 old->optimize =
6805 323 ((old->optimize & new_fields->optimize & KEY_OPTIMIZE_EXISTS) |
6806 323 ((old->optimize | new_fields->optimize) &
6807 KEY_OPTIMIZE_REF_OR_NULL));
6808 323 old->null_rejecting =
6809
3/4
✓ Branch 0 taken 291 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 291 times.
✗ Branch 3 not taken.
323 (old->null_rejecting && new_fields->null_rejecting);
6810
4/6
✓ Branch 0 taken 2142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2142 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 360 times.
✓ Branch 5 taken 1782 times.
4284 } else if (old->eq_func && new_fields->eq_func &&
6811
4/4
✓ Branch 0 taken 2024 times.
✓ Branch 1 taken 118 times.
✓ Branch 2 taken 1909 times.
✓ Branch 3 taken 115 times.
2142 ((old->val->const_item() && old->val->is_null()) ||
6812
2/2
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 1782 times.
2027 new_fields->val->is_null())) {
6813 /* field = expression OR field IS NULL */
6814 360 old->level = and_level;
6815 360 old->optimize = KEY_OPTIMIZE_REF_OR_NULL;
6816 /*
6817 Remember the NOT NULL value unless the value does not depend
6818 on other tables.
6819 */
6820
6/6
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 95 times.
✓ Branch 2 taken 115 times.
✓ Branch 3 taken 150 times.
✓ Branch 4 taken 115 times.
✓ Branch 5 taken 245 times.
360 if (!old->val->used_tables() && old->val->is_null())
6821 115 old->val = new_fields->val;
6822 /* The referred expression can be NULL: */
6823 360 old->null_rejecting = false;
6824 } else {
6825 /*
6826 We are comparing two different const. In this case we can't
6827 use a key-lookup on this so it's better to remove the value
6828 and let the range optimizer handle it
6829 */
6830
2/2
✓ Branch 0 taken 1653 times.
✓ Branch 1 taken 129 times.
1782 if (old == --first_free) // If last item
6831 1653 break;
6832 129 *old = *first_free; // Remove old value
6833 129 old--; // Retry this value
6834 }
6835 }
6836 }
6837 }
6838 /* Remove all not used items */
6839
2/2
✓ Branch 0 taken 1960 times.
✓ Branch 1 taken 2113 times.
4073 for (Key_field *old = start; old != first_free;) {
6840
2/2
✓ Branch 0 taken 818 times.
✓ Branch 1 taken 1142 times.
1960 if (old->level != and_level) { // Not used in all levels
6841
2/2
✓ Branch 0 taken 588 times.
✓ Branch 1 taken 230 times.
818 if (old == --first_free) break;
6842 230 *old = *first_free; // Remove old value
6843 230 continue;
6844 }
6845 1142 old++;
6846 }
6847 2701 return first_free;
6848 }
6849
6850 /**
6851 Given a field, return its index in semi-join's select list, or UINT_MAX
6852
6853 @param item_field Field to be looked up in select list
6854
6855 @retval =UINT_MAX Field is not from a semijoin-transformed subquery
6856 @retval <UINT_MAX Index in select list of subquery
6857
6858 @details
6859 Given a field, find its table; then see if the table is within a
6860 semi-join nest and if the field was in select list of the subquery
6861 (if subquery was part of a quantified comparison predicate), or
6862 the field was a result of subquery decorrelation.
6863 If it was, then return the field's index in the select list.
6864 The value is used by LooseScan strategy.
6865 */
6866
6867 4837597 static uint get_semi_join_select_list_index(Item_field *item_field) {
6868 4837597 TABLE_LIST *emb_sj_nest = item_field->table_ref->embedding;
6869
6/6
✓ Branch 0 taken 18721 times.
✓ Branch 1 taken 4818876 times.
✓ Branch 2 taken 16225 times.
✓ Branch 3 taken 2496 times.
✓ Branch 4 taken 16225 times.
✓ Branch 5 taken 4821372 times.
4837597 if (emb_sj_nest && emb_sj_nest->is_sj_or_aj_nest()) {
6870 16225 const mem_root_deque<Item *> &items =
6871 16225 emb_sj_nest->nested_join->sj_inner_exprs;
6872
2/2
✓ Branch 0 taken 16303 times.
✓ Branch 1 taken 13889 times.
30192 for (size_t i = 0; i < items.size(); i++) {
6873 16303 const Item *sel_item = items[i];
6874
4/4
✓ Branch 0 taken 3500 times.
✓ Branch 1 taken 12813 times.
✓ Branch 2 taken 2346 times.
✓ Branch 3 taken 13967 times.
19813 if (sel_item->type() == Item::FIELD_ITEM &&
6875
2/2
✓ Branch 0 taken 2346 times.
✓ Branch 1 taken 1154 times.
3500 down_cast<const Item_field *>(sel_item)->field->eq(item_field->field))
6876 2346 return i;
6877 }
6878 }
6879 4835261 return UINT_MAX;
6880 }
6881
6882 /**
6883 @brief
6884 If EXPLAIN or if the --safe-updates option is enabled, add a warning that an
6885 index cannot be used for ref access.
6886
6887 @details
6888 If EXPLAIN or if the --safe-updates option is enabled, add a warning for each
6889 index that cannot be used for ref access due to either type conversion or
6890 different collations on the field used for comparison
6891
6892 Example type conversion (char compared to int):
6893
6894 CREATE TABLE t1 (url char(1) PRIMARY KEY);
6895 SELECT * FROM t1 WHERE url=1;
6896
6897 Example different collations (danish vs german2):
6898
6899 CREATE TABLE t1 (url char(1) PRIMARY KEY) collate latin1_danish_ci;
6900 SELECT * FROM t1 WHERE url='1' collate latin1_german2_ci;
6901
6902 @param thd Thread for the connection that submitted the query
6903 @param field Field used in comparison
6904 @param cant_use_index Indexes that cannot be used for lookup
6905 */
6906 1336 static void warn_index_not_applicable(THD *thd, const Field *field,
6907 const Key_map cant_use_index) {
6908
1/2
✓ Branch 0 taken 1336 times.
✗ Branch 1 not taken.
1336 Functional_index_error_handler functional_index_error_handler(field, thd);
6909
6910
4/4
✓ Branch 0 taken 1230 times.
✓ Branch 1 taken 106 times.
✓ Branch 2 taken 109 times.
✓ Branch 3 taken 1227 times.
2566 if (thd->lex->is_explain() ||
6911
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1227 times.
1230 thd->variables.option_bits & OPTION_SAFE_UPDATES)
6912
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 109 times.
301 for (uint j = 0; j < field->table->s->keys; j++)
6913
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 94 times.
192 if (cant_use_index.is_set(j))
6914
1/2
✓ Branch 0 taken 98 times.
✗ Branch 1 not taken.
98 push_warning_printf(thd, Sql_condition::SL_WARNING,
6915 ER_WARN_INDEX_NOT_APPLICABLE,
6916 ER_THD(thd, ER_WARN_INDEX_NOT_APPLICABLE), "ref",
6917
1/2
✓ Branch 0 taken 98 times.
✗ Branch 1 not taken.
98 field->table->key_info[j].name, field->field_name);
6918 1336 }
6919
6920 /**
6921 Add a possible key to array of possible keys if it's usable as a key
6922
6923 @param [in,out] key_fields Used as an input parameter in the sense that it is
6924 a pointer to a pointer to a memory area where an array of Key_field objects
6925 will stored. It is used as an out parameter in the sense that the pointer will
6926 be updated to point beyond the last Key_field written.
6927
6928 @param thd session context
6929 @param and_level And level, to be stored in Key_field
6930 @param cond Condition predicate
6931 @param item_field Field used in comparison
6932 @param eq_func True if we used =, <=> or IS NULL
6933 @param value Array of values used for comparison with field
6934 @param num_values Number of elements in the array of values
6935 @param usable_tables Tables which can be used for key optimization
6936 @param sargables IN/OUT Array of found sargable candidates.
6937 Will be ignored in case eq_func is true.
6938
6939 @note
6940 If we are doing a NOT NULL comparison on a NOT NULL field in a outer join
6941 table, we store this to be able to do not exists optimization later.
6942
6943
6944 @returns false if success, true if error
6945 */
6946
6947 6942079 static bool add_key_field(THD *thd, Key_field **key_fields, uint and_level,
6948 Item_func *cond, Item_field *item_field, bool eq_func,
6949 Item **value, uint num_values,
6950 table_map usable_tables, SARGABLE_PARAM **sargables) {
6951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6942092 times.
6942079 assert(cond->is_bool_func());
6952
3/4
✓ Branch 0 taken 629675 times.
✓ Branch 1 taken 6312417 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 629675 times.
6942092 assert(eq_func || sargables);
6953
47/48
✓ Branch 0 taken 6702831 times.
✓ Branch 1 taken 239261 times.
✓ Branch 2 taken 6449663 times.
✓ Branch 3 taken 253169 times.
✓ Branch 4 taken 6440159 times.
✓ Branch 5 taken 9504 times.
✓ Branch 6 taken 6428722 times.
✓ Branch 7 taken 11434 times.
✓ Branch 8 taken 6422047 times.
✓ Branch 9 taken 6676 times.
✓ Branch 10 taken 6416399 times.
✓ Branch 11 taken 5631 times.
✓ Branch 12 taken 355883 times.
✓ Branch 13 taken 6060514 times.
✓ Branch 14 taken 353285 times.
✓ Branch 15 taken 2598 times.
✓ Branch 16 taken 193007 times.
✓ Branch 17 taken 160278 times.
✓ Branch 18 taken 184480 times.
✓ Branch 19 taken 8527 times.
✓ Branch 20 taken 176321 times.
✓ Branch 21 taken 8159 times.
✓ Branch 22 taken 169955 times.
✓ Branch 23 taken 6366 times.
✓ Branch 24 taken 918 times.
✓ Branch 25 taken 169037 times.
✓ Branch 26 taken 477 times.
✓ Branch 27 taken 441 times.
✓ Branch 28 taken 428 times.
✓ Branch 29 taken 49 times.
✓ Branch 30 taken 302 times.
✓ Branch 31 taken 126 times.
✓ Branch 32 taken 225 times.
✓ Branch 33 taken 77 times.
✓ Branch 34 taken 164 times.
✓ Branch 35 taken 61 times.
✓ Branch 36 taken 127 times.
✓ Branch 37 taken 37 times.
✓ Branch 38 taken 119 times.
✓ Branch 39 taken 8 times.
✓ Branch 40 taken 109 times.
✓ Branch 41 taken 10 times.
✓ Branch 42 taken 62 times.
✓ Branch 43 taken 47 times.
✓ Branch 44 taken 22 times.
✓ Branch 45 taken 40 times.
✓ Branch 46 taken 32 times.
✗ Branch 47 not taken.
6942092 assert(cond->functype() == Item_func::EQ_FUNC ||
6954 cond->functype() == Item_func::NE_FUNC ||
6955 cond->functype() == Item_func::GT_FUNC ||
6956 cond->functype() == Item_func::LT_FUNC ||
6957 cond->functype() == Item_func::GE_FUNC ||
6958 cond->functype() == Item_func::LE_FUNC ||
6959 cond->functype() == Item_func::MULT_EQUAL_FUNC ||
6960 cond->functype() == Item_func::EQUAL_FUNC ||
6961 cond->functype() == Item_func::LIKE_FUNC ||
6962 cond->functype() == Item_func::ISNULL_FUNC ||
6963 cond->functype() == Item_func::ISNOTNULL_FUNC ||
6964 cond->functype() == Item_func::BETWEEN ||
6965 cond->functype() == Item_func::IN_FUNC ||
6966 cond->functype() == Item_func::MEMBER_OF_FUNC ||
6967 cond->functype() == Item_func::SP_EQUALS_FUNC ||
6968 cond->functype() == Item_func::SP_WITHIN_FUNC ||
6969 cond->functype() == Item_func::SP_CONTAINS_FUNC ||
6970 cond->functype() == Item_func::SP_INTERSECTS_FUNC ||
6971 cond->functype() == Item_func::SP_DISJOINT_FUNC ||
6972 cond->functype() == Item_func::SP_COVERS_FUNC ||
6973 cond->functype() == Item_func::SP_COVEREDBY_FUNC ||
6974 cond->functype() == Item_func::SP_OVERLAPS_FUNC ||
6975 cond->functype() == Item_func::SP_TOUCHES_FUNC ||
6976 cond->functype() == Item_func::SP_CROSSES_FUNC);
6977
6978 6942040 Field *const field = item_field->field;
6979 6942040 TABLE_LIST *const tl = item_field->table_ref;
6980
6981
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6942037 times.
6942040 if (tl->table->reginfo.join_tab == nullptr) {
6982 /*
6983 Due to a bug in IN-to-EXISTS (grep for real_item() in item_subselect.cc
6984 for more info), an index over a field from an outer query might be
6985 considered here, which is incorrect. Their query has been fully
6986 optimized already so their reginfo.join_tab is NULL and we reject them.
6987 */
6988 3 return false;
6989 }
6990
6991
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6942073 times.
6942037 DBUG_PRINT("info", ("add_key_field for field %s", field->field_name));
6992 6942078 uint exists_optimize = 0;
6993
5/6
✓ Branch 0 taken 6942080 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2955 times.
✓ Branch 3 taken 6939128 times.
✓ Branch 4 taken 1669 times.
✓ Branch 5 taken 6940412 times.
6945033 if (!tl->derived_keys_ready && tl->uses_materialization() &&
6994
2/2
✓ Branch 0 taken 1669 times.
✓ Branch 1 taken 1286 times.
2955 !tl->table->is_created()) {
6995 bool allocated;
6996
2/4
✓ Branch 0 taken 1669 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1669 times.
1669 if (tl->update_derived_keys(thd, field, value, num_values, &allocated))
6997 92 return true;
6998
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 1577 times.
1669 if (!allocated) return false;
6999 }
7000
2/2
✓ Branch 0 taken 1244632 times.
✓ Branch 1 taken 5697349 times.
6941989 if (!field->is_flag_set(PART_KEY_FLAG)) {
7001 // Don't remove column IS NULL on a LEFT JOIN table
7002
2/2
✓ Branch 0 taken 3468 times.
✓ Branch 1 taken 952150 times.
955618 if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
7003
8/8
✓ Branch 0 taken 955618 times.
✓ Branch 1 taken 289014 times.
✓ Branch 2 taken 808 times.
✓ Branch 3 taken 2660 times.
✓ Branch 4 taken 637 times.
✓ Branch 5 taken 168 times.
✓ Branch 6 taken 1244461 times.
✓ Branch 7 taken 168 times.
2200250 !tl->table->is_nullable() || field->is_nullable())
7004 1244461 return false; // Not a key. Skip it
7005 168 exists_optimize = KEY_OPTIMIZE_EXISTS;
7006
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 assert(num_values == 1);
7007 } else {
7008 5697349 table_map used_tables = 0;
7009 5697349 bool optimizable = false;
7010
2/2
✓ Branch 0 taken 5941599 times.
✓ Branch 1 taken 5697362 times.
11638961 for (uint i = 0; i < num_values; i++) {
7011 5941599 used_tables |= (value[i])->used_tables();
7012
2/2
✓ Branch 0 taken 5939309 times.
✓ Branch 1 taken 2303 times.
5941605 if (!((value[i])->used_tables() & (tl->map() | RAND_TABLE_BIT)))
7013 5939309 optimizable = true;
7014 }
7015
2/2
✓ Branch 0 taken 2229 times.
✓ Branch 1 taken 5695133 times.
5697362 if (!optimizable) return false;
7016
2/2
✓ Branch 0 taken 518071 times.
✓ Branch 1 taken 5177012 times.
5695133 if (!(usable_tables & tl->map())) {
7017
2/2
✓ Branch 0 taken 2264 times.
✓ Branch 1 taken 514361 times.
516624 if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
7018
8/8
✓ Branch 0 taken 516624 times.
✓ Branch 1 taken 1447 times.
✓ Branch 2 taken 2248 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 2140 times.
✓ Branch 5 taken 112 times.
✓ Branch 6 taken 517964 times.
✓ Branch 7 taken 112 times.
1034696 !tl->table->is_nullable() || field->is_nullable())
7019 517964 return false; // Can't use left join optimize
7020 112 exists_optimize = KEY_OPTIMIZE_EXISTS;
7021 } else {
7022 5177012 JOIN_TAB *stat = tl->table->reginfo.join_tab;
7023 5177012 Key_map possible_keys = field->key_start;
7024 5177012 possible_keys.intersect(tl->table->keys_in_use_for_query);
7025 5177054 stat[0].keys().merge(possible_keys); // Add possible keys
7026
7027 /*
7028 Save the following cases:
7029 Field op constant
7030 Field LIKE constant where constant doesn't start with a wildcard
7031 Field = field2 where field2 is in a different table
7032 Field op formula
7033 Field IS NULL
7034 Field IS NOT NULL
7035 Field BETWEEN ...
7036 Field IN ...
7037 */
7038 5177062 stat[0].key_dependent |= used_tables;
7039
7040 5177062 bool is_const = true;
7041
2/2
✓ Branch 0 taken 5421112 times.
✓ Branch 1 taken 1322929 times.
6744041 for (uint i = 0; i < num_values; i++) {
7042
3/4
✓ Branch 0 taken 5421117 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3854138 times.
✓ Branch 3 taken 1566979 times.
5421112 if (!(is_const &= value[i]->const_for_execution())) break;
7043 }
7044
2/2
✓ Branch 0 taken 1322929 times.
✓ Branch 1 taken 3854138 times.
5177067 if (is_const)
7045 1322929 stat[0].const_keys.merge(possible_keys);
7046
2/2
✓ Branch 0 taken 1130 times.
✓ Branch 1 taken 3853008 times.
3854138 else if (!eq_func) {
7047 /*
7048 Save info to be able check whether this predicate can be
7049 considered as sargable for range analysis after reading const tables.
7050 We do not save info about equalities as update_const_equal_items
7051 will take care of updating info on keys from sargable equalities.
7052 */
7053
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1130 times.
1130 assert(sargables);
7054 1130 (*sargables)--;
7055 /*
7056 The sargables and key_fields arrays share the same memory
7057 buffer, and grow from opposite directions, so make sure they
7058 don't cross.
7059 */
7060
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1130 times.
1130 assert(*sargables > reinterpret_cast<SARGABLE_PARAM *>(*key_fields));
7061 1130 (*sargables)->field = field;
7062 1130 (*sargables)->arg_value = value;
7063 1130 (*sargables)->num_values = num_values;
7064 }
7065 /*
7066 We can't always use indexes when comparing a string index to a
7067 number. cmp_type() is checked to allow compare of dates to numbers.
7068 eq_func is NEVER true when num_values > 1
7069 */
7070
2/2
✓ Branch 0 taken 338390 times.
✓ Branch 1 taken 4838667 times.
5178393 if (!eq_func) return false;
7071
7072 /*
7073 Check if the field and value are comparable in the index.
7074 */
7075
2/4
✓ Branch 0 taken 4838671 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4838674 times.
✗ Branch 3 not taken.
4838667 if (!comparable_in_index(cond, field, Field::itRAW, cond->functype(),
7076
4/4
✓ Branch 0 taken 4837562 times.
✓ Branch 1 taken 1112 times.
✓ Branch 2 taken 1336 times.
✓ Branch 3 taken 4837334 times.
9676232 *value) ||
7077
3/4
✓ Branch 0 taken 4837554 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 661632 times.
✓ Branch 3 taken 4175922 times.
4837562 (field->cmp_type() == STRING_RESULT &&
7078
3/4
✓ Branch 0 taken 661629 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 661277 times.
✓ Branch 3 taken 352 times.
661632 field->match_collation_to_optimize_range() &&
7079
4/6
✓ Branch 0 taken 661279 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 661284 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 224 times.
✓ Branch 5 taken 661060 times.
661277 field->charset() != cond->compare_collation())) {
7080
1/2
✓ Branch 0 taken 1336 times.
✗ Branch 1 not taken.
1336 warn_index_not_applicable(stat->join()->thd, field, possible_keys);
7081 1336 return false;
7082 }
7083 }
7084 }
7085 /*
7086 For the moment eq_func is always true. This slot is reserved for future
7087 extensions where we want to remembers other things than just eq comparisons
7088 */
7089
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4837614 times.
4837614 assert(eq_func);
7090 /*
7091 Calculate the "null rejecting" property based on the type of predicate.
7092 Only the <=> operator and the IS NULL and IS NOT NULL clauses may return
7093 true on nullable operands that have the NULL value - assuming that all
7094 other predicates are augmented with IS TRUE or IS FALSE truth clause,
7095 so that all UNKNOWN results are converted to TRUE or FALSE.
7096
7097 The "null rejecting" property can be combined with the left and right
7098 operands to perform certain optimizations.
7099
7100 If the condition has form "left.field = right.keypart" and left.field can
7101 be NULL, there will be no matches if left.field is NULL.
7102 We use null_rejecting in add_not_null_conds() to add
7103 'left.field IS NOT NULL' to tab->m_condition, if this is not an outer
7104 join. We also use it to shortcut reading rows from table "right" when
7105 left.field is found to be a NULL value (in RefIterator and BKA).
7106
7107 It is also possible to apply optimizations to the indexed table.
7108 If the operation is null rejecting and there is a unique index over
7109 the key field, an eq_ref operation can be performed on the index, since
7110 we have no interest in the NULL values.
7111
7112 Notice however that the null rejecting property may be cancelled out
7113 by the KEY_OPTIMIZE_REF_OR_NULL property: this can be set when having:
7114
7115 left.field = right.keypart OR right.keypart IS NULL.
7116 */
7117 4837614 const bool null_rejecting = cond->functype() != Item_func::EQUAL_FUNC &&
7118
4/4
✓ Branch 0 taken 4836328 times.
✓ Branch 1 taken 1289 times.
✓ Branch 2 taken 4833171 times.
✓ Branch 3 taken 3154 times.
9670780 cond->functype() != Item_func::ISNULL_FUNC &&
7119
1/2
✓ Branch 0 taken 4833183 times.
✗ Branch 1 not taken.
4833171 cond->functype() != Item_func::ISNOTNULL_FUNC;
7120
7121 /* Store possible eq field */
7122 4837607 new (*key_fields) Key_field(item_field, *value, and_level, exists_optimize,
7123 eq_func, null_rejecting, nullptr,
7124 4837606 get_semi_join_select_list_index(item_field));
7125 4837609 (*key_fields)++;
7126 /*
7127 The sargables and key_fields arrays share the same memory buffer,
7128 and grow from opposite directions, so make sure they don't
7129 cross. But if sargables was NULL, eq_func had to be true and we
7130 don't write any sargables.
7131 */
7132
3/4
✓ Branch 0 taken 4836938 times.
✓ Branch 1 taken 671 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4836938 times.
4837609 assert(sargables == nullptr ||
7133 *key_fields < reinterpret_cast<Key_field *>(*sargables));
7134
7135 4837609 return false;
7136 }
7137
7138 /**
7139 Add possible keys to array of possible keys originated from a simple
7140 predicate.
7141
7142 @param thd session context
7143 @param[in,out] key_fields Pointer to add key, if usable
7144 is incremented if key was stored in the array
7145 @param and_level And level, to be stored in Key_field
7146 @param cond Condition predicate
7147 @param field_item Field used in comparison
7148 @param eq_func True if we used =, <=> or IS NULL
7149 @param val Value used for comparison with field
7150 Is NULL for BETWEEN and IN
7151 @param num_values Number of elements in the array of values
7152 @param usable_tables Tables which can be used for key optimization
7153 @param sargables IN/OUT Array of found sargable candidates
7154
7155 @note
7156 If field items f1 and f2 belong to the same multiple equality and
7157 a key is added for f1, the the same key is added for f2.
7158
7159 @returns false if success, true if error
7160 */
7161
7162 877895 static bool add_key_equal_fields(THD *thd, Key_field **key_fields,
7163 uint and_level, Item_func *cond,
7164 Item_field *field_item, bool eq_func,
7165 Item **val, uint num_values,
7166 table_map usable_tables,
7167 SARGABLE_PARAM **sargables) {
7168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 877896 times.
877895 assert(cond->is_bool_func());
7169
7170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 877895 times.
877896 if (add_key_field(thd, key_fields, and_level, cond, field_item, eq_func, val,
7171 num_values, usable_tables, sargables))
7172 return true;
7173 877895 Item_equal *item_equal = field_item->item_equal;
7174
2/2
✓ Branch 0 taken 875147 times.
✓ Branch 1 taken 2748 times.
877895 if (item_equal == nullptr) return false;
7175 /*
7176 Add to the set of possible key values every substitution of
7177 the field for an equal field included into item_equal
7178 */
7179
5/8
✓ Branch 0 taken 2749 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2749 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8210 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5461 times.
✓ Branch 7 taken 2749 times.
8210 for (Item_field &item : item_equal->get_fields()) {
7180
3/4
✓ Branch 0 taken 5461 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2712 times.
✓ Branch 3 taken 2749 times.
5461 if (!field_item->field->eq(item.field)) {
7181
2/4
✓ Branch 0 taken 2712 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2712 times.
2712 if (add_key_field(thd, key_fields, and_level, cond, &item, eq_func, val,
7182 num_values, usable_tables, sargables))
7183 return true;
7184 }
7185 }
7186 2749 return false;
7187 }
7188
7189 /**
7190 Check if an expression is a non-outer field.
7191
7192 Checks if an expression is a field and belongs to the current select.
7193
7194 @param field Item expression to check
7195
7196 @return boolean
7197 @retval true the expression is a local field
7198 @retval false it's something else
7199 */
7200
7201 2238982 static bool is_local_field(Item *field) {
7202 2238982 return field->real_item()->type() == Item::FIELD_ITEM &&
7203
2/2
✓ Branch 0 taken 875501 times.
✓ Branch 1 taken 2023 times.
877524 !field->is_outer_reference() &&
7204
4/4
✓ Branch 0 taken 877524 times.
✓ Branch 1 taken 1361470 times.
✓ Branch 2 taken 875494 times.
✓ Branch 3 taken 7 times.
3992015 !down_cast<Item_ident *>(field)->depended_from &&
7205
2/2
✓ Branch 0 taken 875494 times.
✓ Branch 1 taken 3 times.
3114491 !down_cast<Item_ident *>(field->real_item())->depended_from;
7206 }
7207
7208 /**
7209 Check if a row constructor expression is over columns in the same query block.
7210
7211 @param item_row Row expression to check.
7212
7213 @return boolean
7214 @retval true The expression is a local column reference.
7215 @retval false It's something else.
7216 */
7217 229 static bool is_row_of_local_columns(Item_row *item_row) {
7218
2/2
✓ Branch 0 taken 488 times.
✓ Branch 1 taken 205 times.
693 for (uint i = 0; i < item_row->cols(); ++i)
7219
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 464 times.
488 if (!is_local_field(item_row->element_index(i))) return false;
7220 205 return true;
7221 }
7222
7223 /**
7224 The guts of the ref optimizer. This function, along with the other
7225 add_key_* functions, make up a recursive procedure that analyzes a
7226 condition expression (a tree of AND and OR predicates) and does
7227 many things.
7228
7229 @param thd session context
7230 @param join The query block involving the condition.
7231 @param [in,out] key_fields Start of memory buffer, see below.
7232 @param [in,out] and_level Current 'and level', see below.
7233 @param cond The conditional expression to analyze.
7234 @param usable_tables Tables not in this bitmap will not be examined.
7235 @param [in,out] sargables End of memory buffer, see below.
7236
7237 @returns false if success, true if error
7238
7239 This documentation is the result of reverse engineering and may
7240 therefore not capture the full gist of the procedure, but it is
7241 known to do the following:
7242
7243 - Populate a raw memory buffer from two directions at the same time. An
7244 'array' of Key_field objects fill the buffer from low to high addresses
7245 whilst an 'array' of SARGABLE_PARAM's fills the buffer from high to low
7246 addresses. At the first call to this function, it is assumed that
7247 key_fields points to the beginning of the buffer and sargables point to the
7248 end (except for a poor-mans 'null element' at the very end).
7249
7250 - Update a number of properties in the JOIN_TAB's that can be used
7251 to find search keys (sargables).
7252
7253 - JOIN_TAB::keys
7254 - JOIN_TAB::key_dependent
7255 - JOIN_TAB::const_keys (dictates if the range optimizer will be run
7256 later.)
7257
7258 The Key_field objects are marked with something called an 'and_level', which
7259 does @b not correspond to their nesting depth within the expression tree. It
7260 is rather a tag to group conjunctions together. For instance, in the
7261 conditional expression
7262
7263 @code
7264 a = 0 AND b = 0
7265 @endcode
7266
7267 two Key_field's are produced, both having an and_level of 0.
7268
7269 In an expression such as
7270
7271 @code
7272 a = 0 AND b = 0 OR a = 1
7273 @endcode
7274
7275 three Key_field's are produced, the first two corresponding to 'a = 0' and
7276 'b = 0', respectively, both with and_level 0. The third one corresponds to
7277 'a = 1' and has an and_level of 1.
7278
7279 A separate function, merge_key_fields() performs ref access validation on
7280 the Key_field array on the recursice ascent. If some Key_field's cannot be
7281 used for ref access, the key_fields pointer is rolled back. All other
7282 modifications to the query plan remain.
7283 */
7284 5907127 bool add_key_fields(THD *thd, JOIN *join, Key_field **key_fields,
7285 uint *and_level, Item *cond, table_map usable_tables,
7286 SARGABLE_PARAM **sargables) {
7287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5907140 times.
5907127 assert(cond->is_bool_func());
7288
7289
2/2
✓ Branch 0 taken 975354 times.
✓ Branch 1 taken 4931785 times.
5907140 if (cond->type() == Item_func::COND_ITEM) {
7290
1/2
✓ Branch 0 taken 975360 times.
✗ Branch 1 not taken.
975354 List_iterator_fast<Item> li(*((Item_cond *)cond)->argument_list());
7291 975360 Key_field *org_key_fields = *key_fields;
7292
7293
3/4
✓ Branch 0 taken 975354 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 955269 times.
✓ Branch 3 taken 20085 times.
975360 if (down_cast<Item_cond *>(cond)->functype() == Item_func::COND_AND_FUNC) {
7294 Item *item;
7295
2/2
✓ Branch 0 taken 4147362 times.
✓ Branch 1 taken 955273 times.
5102634 while ((item = li++)) {
7296
2/4
✓ Branch 0 taken 4147365 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4147365 times.
4147362 if (add_key_fields(thd, join, key_fields, and_level, item,
7297 usable_tables, sargables))
7298 return true;
7299 }
7300
2/2
✓ Branch 0 taken 3992919 times.
✓ Branch 1 taken 955273 times.
4948192 for (; org_key_fields != *key_fields; org_key_fields++)
7301 3992919 org_key_fields->level = *and_level;
7302 } else {
7303 20085 (*and_level)++;
7304
2/4
✓ Branch 0 taken 20085 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20085 times.
20085 if (add_key_fields(thd, join, key_fields, and_level, li++, usable_tables,
7305 sargables))
7306 return true;
7307 Item *item;
7308
2/2
✓ Branch 0 taken 30250 times.
✓ Branch 1 taken 20087 times.
50337 while ((item = li++)) {
7309 30250 Key_field *start_key_fields = *key_fields;
7310 30250 (*and_level)++;
7311
2/4
✓ Branch 0 taken 30252 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30252 times.
30250 if (add_key_fields(thd, join, key_fields, and_level, item,
7312 usable_tables, sargables))
7313 return true;
7314 30252 *key_fields = merge_key_fields(org_key_fields, start_key_fields,
7315
1/2
✓ Branch 0 taken 30252 times.
✗ Branch 1 not taken.
30252 *key_fields, ++(*and_level));
7316 }
7317 }
7318 975360 return false;
7319 }
7320
7321 /*
7322 Subquery optimization: Conditions that are pushed down into subqueries
7323 are wrapped into Item_func_trig_cond. We process the wrapped condition
7324 but need to set cond_guard for Key_use elements generated from it.
7325 */
7326
4/4
✓ Branch 0 taken 4931745 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 486 times.
✓ Branch 3 taken 4931297 times.
9863544 if (cond->type() == Item::FUNC_ITEM &&
7327
2/2
✓ Branch 0 taken 486 times.
✓ Branch 1 taken 4931273 times.
4931745 down_cast<Item_func *>(cond)->functype() == Item_func::TRIG_COND_FUNC) {
7328 486 Item *const cond_arg = down_cast<Item_func *>(cond)->arguments()[0];
7329
1/2
✓ Branch 0 taken 486 times.
✗ Branch 1 not taken.
972 if (join->group_list.empty() && join->order.empty() &&
7330
1/2
✓ Branch 0 taken 486 times.
✗ Branch 1 not taken.
486 join->query_expression()->item &&
7331
5/6
✓ Branch 0 taken 486 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 418 times.
✓ Branch 3 taken 68 times.
✓ Branch 4 taken 417 times.
✓ Branch 5 taken 69 times.
1390 join->query_expression()->item->substype() == Item_subselect::IN_SUBS &&
7332
2/2
✓ Branch 0 taken 417 times.
✓ Branch 1 taken 1 times.
418 !join->query_expression()->is_union()) {
7333 417 Key_field *save = *key_fields;
7334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 417 times.
417 if (add_key_fields(thd, join, key_fields, and_level, cond_arg,
7335 usable_tables, sargables))
7336 return true;
7337 // Indicate that this ref access candidate is for subquery lookup:
7338
2/2
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 417 times.
498 for (; save != *key_fields; save++)
7339 81 save->cond_guard = ((Item_func_trig_cond *)cond)->get_trig_var();
7340 }
7341 486 return false;
7342 }
7343
7344 /* If item is of type 'field op field/constant' add it to key_fields */
7345
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 4931245 times.
4931297 if (cond->type() != Item::FUNC_ITEM) return false;
7346 4931245 Item_func *const cond_func = down_cast<Item_func *>(cond);
7347 4931263 auto optimize = cond_func->select_optimize(thd);
7348 // Catch errors that might be thrown during select_optimize()
7349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4931232 times.
4931260 if (thd->is_error()) return true;
7350
5/6
✓ Branch 0 taken 235980 times.
✓ Branch 1 taken 1127192 times.
✓ Branch 2 taken 413648 times.
✓ Branch 3 taken 17266 times.
✓ Branch 4 taken 3137157 times.
✗ Branch 5 not taken.
4931232 switch (optimize) {
7351 235980 case Item_func::OPTIMIZE_NONE:
7352 4931240 break;
7353 1127192 case Item_func::OPTIMIZE_KEY: {
7354 Item **values;
7355 /*
7356 Build list of possible keys for 'a BETWEEN low AND high'.
7357 It is handled similar to the equivalent condition
7358 'a >= low AND a <= high':
7359 */
7360
3/4
✓ Branch 0 taken 1127201 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7091 times.
✓ Branch 3 taken 1120110 times.
1127192 if (cond_func->functype() == Item_func::BETWEEN) {
7361 Item_field *field_item;
7362 7091 bool equal_func = false;
7363 7091 uint num_values = 2;
7364
1/2
✓ Branch 0 taken 7091 times.
✗ Branch 1 not taken.
7091 values = cond_func->arguments();
7365
7366 bool binary_cmp =
7367
2/4
✓ Branch 0 taken 7091 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7091 times.
✗ Branch 3 not taken.
7091 (values[0]->real_item()->type() == Item::FIELD_ITEM)
7368
6/8
✓ Branch 0 taken 5854 times.
✓ Branch 1 taken 1237 times.
✓ Branch 2 taken 5854 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5854 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5641 times.
✓ Branch 7 taken 213 times.
7091 ? ((Item_field *)values[0]->real_item())->field->binary()
7369 7091 : true;
7370
7371 /*
7372 Additional optimization: If 'low = high':
7373 Handle as if the condition was "t.key = low".
7374 */
7375
4/4
✓ Branch 0 taken 6929 times.
✓ Branch 1 taken 162 times.
✓ Branch 2 taken 75 times.
✓ Branch 3 taken 7016 times.
14020 if (!((Item_func_between *)cond_func)->negated &&
7376
3/4
✓ Branch 0 taken 6929 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 75 times.
✓ Branch 3 taken 6854 times.
6929 values[1]->eq(values[2], binary_cmp)) {
7377 75 equal_func = true;
7378 75 num_values = 1;
7379 }
7380
7381 /*
7382 Append keys for 'field <cmp> value[]' if the
7383 condition is of the form::
7384 '<field> BETWEEN value[1] AND value[2]'
7385 */
7386
3/4
✓ Branch 0 taken 7091 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5854 times.
✓ Branch 3 taken 1237 times.
7091 if (is_local_field(values[0])) {
7387
1/2
✓ Branch 0 taken 5854 times.
✗ Branch 1 not taken.
5854 field_item = (Item_field *)(values[0]->real_item());
7388
2/4
✓ Branch 0 taken 5854 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5854 times.
5854 if (add_key_equal_fields(thd, key_fields, *and_level, cond_func,
7389 field_item, equal_func, &values[1],
7390 num_values, usable_tables, sargables))
7391 return true;
7392 }
7393 /*
7394 Append keys for 'value[0] <cmp> field' if the
7395 condition is of the form:
7396 'value[0] BETWEEN field1 AND field2'
7397 */
7398
2/2
✓ Branch 0 taken 14107 times.
✓ Branch 1 taken 7091 times.
21198 for (uint i = 1; i <= num_values; i++) {
7399
3/4
✓ Branch 0 taken 14107 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 394 times.
✓ Branch 3 taken 13713 times.
14107 if (is_local_field(values[i])) {
7400
1/2
✓ Branch 0 taken 394 times.
✗ Branch 1 not taken.
394 field_item = (Item_field *)(values[i]->real_item());
7401
2/4
✓ Branch 0 taken 394 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 394 times.
394 if (add_key_equal_fields(thd, key_fields, *and_level, cond_func,
7402 field_item, equal_func, values, 1,
7403 usable_tables, sargables))
7404 return true;
7405 }
7406 }
7407 } // if ( ... Item_func::BETWEEN)
7408
5/6
✓ Branch 0 taken 1120100 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 462 times.
✓ Branch 3 taken 1119638 times.
✓ Branch 4 taken 441 times.
✓ Branch 5 taken 1119659 times.
1120572 else if (cond_func->functype() == Item_func::MEMBER_OF_FUNC &&
7409
4/6
✓ Branch 0 taken 462 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 462 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 441 times.
✓ Branch 5 taken 21 times.
462 is_local_field(cond_func->key_item())) {
7410 // The predicate is <val> IN (<typed array>)
7411
1/2
✓ Branch 0 taken 441 times.
✗ Branch 1 not taken.
441 add_key_equal_fields(thd, key_fields, *and_level, cond_func,
7412
3/6
✓ Branch 0 taken 441 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 441 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 434 times.
✗ Branch 5 not taken.
441 (Item_field *)(cond_func->key_item()->real_item()),
7413 true, cond_func->arguments(), 1, usable_tables,
7414 sargables);
7415
5/6
✓ Branch 0 taken 1119659 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1119526 times.
✓ Branch 3 taken 133 times.
✓ Branch 4 taken 255 times.
✓ Branch 5 taken 1119408 times.
2239189 } else if (cond_func->functype() == Item_func::JSON_CONTAINS ||
7416
3/4
✓ Branch 0 taken 1119530 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 1119413 times.
1119526 cond_func->functype() == Item_func::JSON_OVERLAPS) {
7417 /*
7418 Applicability analysis was done during substitute_gc().
7419 Check here that a typed array field is used and there's a key over
7420 it.
7421 1) func has a key item
7422 2) key item is a local field
7423 3) key item is a typed array field
7424 If so, mark appropriate index as available for range optimizer
7425 */
7426
1/2
✓ Branch 0 taken 255 times.
✗ Branch 1 not taken.
255 if (!cond_func->key_item() || // 1
7427
8/10
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 244 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 244 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 212 times.
✓ Branch 7 taken 32 times.
✓ Branch 8 taken 43 times.
✓ Branch 9 taken 212 times.
467 !is_local_field(cond_func->key_item()) || // 2
7428
3/6
✓ Branch 0 taken 212 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 212 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 212 times.
212 !cond_func->key_item()->returns_array()) // 3
7429 43 break;
7430 const Field *field =
7431
1/2
✓ Branch 0 taken 212 times.
✗ Branch 1 not taken.
212 (down_cast<const Item_field *>(cond_func->key_item()))->field;
7432 212 JOIN_TAB *tab = field->table->reginfo.join_tab;
7433 212 Key_map possible_keys = field->key_start;
7434
7435 212 possible_keys.intersect(field->table->keys_in_use_for_query);
7436 212 tab->keys().merge(possible_keys); // Add possible keys
7437 212 tab->const_keys.merge(possible_keys); // Add possible keys
7438 } // if (... Item_func::CONTAINS)
7439 // The predicate is IN or <>
7440
6/8
✓ Branch 0 taken 1119403 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1119417 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 420576 times.
✓ Branch 5 taken 698841 times.
✓ Branch 6 taken 420557 times.
✓ Branch 7 taken 698860 times.
1539984 else if (is_local_field(cond_func->key_item()) &&
7441
3/4
✓ Branch 0 taken 420576 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 420557 times.
✓ Branch 3 taken 19 times.
420576 !cond_func->is_outer_reference()) {
7442
1/2
✓ Branch 0 taken 420557 times.
✗ Branch 1 not taken.
420557 values = cond_func->arguments() + 1;
7443
5/6
✓ Branch 0 taken 420557 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 252625 times.
✓ Branch 3 taken 167932 times.
✓ Branch 4 taken 844 times.
✓ Branch 5 taken 419713 times.
673182 if (cond_func->functype() == Item_func::NE_FUNC &&
7444
4/6
✓ Branch 0 taken 252625 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 252625 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 844 times.
✓ Branch 5 taken 251781 times.
252625 is_local_field(cond_func->arguments()[1]))
7445 844 values--;
7446
5/8
✓ Branch 0 taken 420557 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 167932 times.
✓ Branch 3 taken 252625 times.
✓ Branch 4 taken 167932 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 167932 times.
420557 assert(cond_func->functype() != Item_func::IN_FUNC ||
7447 cond_func->argument_count() != 2);
7448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 420557 times.
420557 if (add_key_equal_fields(
7449 thd, key_fields, *and_level, cond_func,
7450
2/4
✓ Branch 0 taken 420557 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 420557 times.
✗ Branch 3 not taken.
420557 (Item_field *)(cond_func->key_item()->real_item()), false,
7451
2/4
✓ Branch 0 taken 420557 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 420557 times.
✗ Branch 3 not taken.
420557 values, cond_func->argument_count() - 1, usable_tables,
7452 sargables))
7453 return true;
7454
5/6
✓ Branch 0 taken 698849 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 962 times.
✓ Branch 3 taken 697887 times.
✓ Branch 4 taken 229 times.
✓ Branch 5 taken 698620 times.
699822 } else if (cond_func->functype() == Item_func::IN_FUNC &&
7455
4/6
✓ Branch 0 taken 962 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 962 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 229 times.
✓ Branch 5 taken 733 times.
962 cond_func->key_item()->type() == Item::ROW_ITEM) {
7456 /*
7457 The condition is (column1, column2, ... ) IN ((const1_1, const1_2),
7458 ...) and there is an index on (column1, column2, ...)
7459
7460 The code below makes sure that the row constructor on the lhs indeed
7461 contains only column references before calling add_key_field on them.
7462
7463 We can't do a ref access on IN, yet here we are. Why? We need
7464 to run add_key_field() only because it verifies that there are
7465 only constant expressions in the rows on the IN's rhs, see
7466 comment above the call to add_key_field() below.
7467
7468 Actually, We could in theory do a ref access if the IN rhs
7469 contained just a single row, but there is a hack in the parser
7470 causing such IN predicates be parsed as row equalities.
7471 */
7472
1/2
✓ Branch 0 taken 229 times.
✗ Branch 1 not taken.
229 Item_row *lhs_row = static_cast<Item_row *>(cond_func->key_item());
7473
3/4
✓ Branch 0 taken 229 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 205 times.
✓ Branch 3 taken 24 times.
229 if (is_row_of_local_columns(lhs_row)) {
7474
3/4
✓ Branch 0 taken 664 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 459 times.
✓ Branch 3 taken 205 times.
664 for (uint i = 0; i < lhs_row->cols(); ++i) {
7475
2/4
✓ Branch 0 taken 459 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 459 times.
✗ Branch 3 not taken.
459 Item *const lhs_item = lhs_row->element_index(i)->real_item();
7476
2/4
✓ Branch 0 taken 459 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 459 times.
459 assert(lhs_item->type() == Item::FIELD_ITEM);
7477 459 Item_field *const lhs_column = static_cast<Item_field *>(lhs_item);
7478 // j goes from 1 since arguments()[0] is the lhs of IN.
7479
3/4
✓ Branch 0 taken 1425 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 966 times.
✓ Branch 3 taken 459 times.
1425 for (uint j = 1; j < cond_func->argument_count(); ++j) {
7480 // Here we pick out the i:th column in the j:th row.
7481
1/2
✓ Branch 0 taken 966 times.
✗ Branch 1 not taken.
966 Item *rhs_item = cond_func->arguments()[j];
7482
2/4
✓ Branch 0 taken 966 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 966 times.
966 assert(rhs_item->type() == Item::ROW_ITEM);
7483 966 Item_row *rhs_row = static_cast<Item_row *>(rhs_item);
7484
3/6
✓ Branch 0 taken 966 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 966 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 966 times.
966 assert(rhs_row->cols() == lhs_row->cols());
7485
1/2
✓ Branch 0 taken 966 times.
✗ Branch 1 not taken.
966 Item **rhs_expr_ptr = rhs_row->addr(i);
7486 /*
7487 add_key_field() will write a Key_field on each call
7488 here, but we don't care, it will never be used. We only
7489 call it for the side effect: update JOIN_TAB::const_keys
7490 so the range optimizer can be invoked. We pass a
7491 scrap buffer and pointer here.
7492 */
7493 966 Key_field scrap_key_field = **key_fields;
7494 966 Key_field *scrap_key_field_ptr = &scrap_key_field;
7495
2/4
✓ Branch 0 taken 966 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 966 times.
966 if (add_key_field(thd, &scrap_key_field_ptr, *and_level,
7496 cond_func, lhs_column,
7497 true, // eq_func
7498 rhs_expr_ptr,
7499 1, // Number of expressions: one
7500 usable_tables,
7501 nullptr)) // sargables
7502 return true;
7503 // The pointer is not supposed to increase by more than one.
7504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 966 times.
966 assert(scrap_key_field_ptr <= &scrap_key_field + 1);
7505 }
7506 }
7507 }
7508 }
7509 1127143 break;
7510 }
7511 413648 case Item_func::OPTIMIZE_OP: {
7512
3/4
✓ Branch 0 taken 413648 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 195020 times.
✓ Branch 3 taken 218628 times.
608669 bool equal_func = (cond_func->functype() == Item_func::EQ_FUNC ||
7513
3/4
✓ Branch 0 taken 195021 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2201 times.
✓ Branch 3 taken 192820 times.
195020 cond_func->functype() == Item_func::EQUAL_FUNC);
7514
7515
4/6
✓ Branch 0 taken 413649 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 413649 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 400226 times.
✓ Branch 5 taken 13423 times.
413649 if (is_local_field(cond_func->arguments()[0])) {
7516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 400225 times.
400225 if (add_key_equal_fields(
7517 thd, key_fields, *and_level, cond_func,
7518
2/4
✓ Branch 0 taken 400226 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 400225 times.
✗ Branch 3 not taken.
400226 (Item_field *)(cond_func->arguments()[0])->real_item(),
7519
2/4
✓ Branch 0 taken 400225 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 400226 times.
✗ Branch 3 not taken.
400226 equal_func, cond_func->arguments() + 1, 1, usable_tables,
7520 sargables))
7521 return true;
7522 } else {
7523
2/4
✓ Branch 0 taken 13423 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13423 times.
✗ Branch 3 not taken.
13423 Item *real_item = cond_func->arguments()[0]->real_item();
7524
3/4
✓ Branch 0 taken 13423 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11437 times.
✓ Branch 3 taken 1986 times.
13423 if (real_item->type() == Item::FUNC_ITEM) {
7525 11437 Item_func *func_item = down_cast<Item_func *>(real_item);
7526
3/4
✓ Branch 0 taken 11437 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3937 times.
✓ Branch 3 taken 7500 times.
11437 if (func_item->functype() == Item_func::COLLATE_FUNC) {
7527
1/2
✓ Branch 0 taken 3937 times.
✗ Branch 1 not taken.
3937 Item *key_item = func_item->key_item();
7528
3/4
✓ Branch 0 taken 3937 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3904 times.
✓ Branch 3 taken 33 times.
3937 if (key_item->type() == Item::FIELD_ITEM) {
7529
2/4
✓ Branch 0 taken 3904 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3904 times.
3904 if (add_key_equal_fields(thd, key_fields, *and_level, cond_func,
7530 down_cast<Item_field *>(key_item),
7531
1/2
✓ Branch 0 taken 3904 times.
✗ Branch 1 not taken.
3904 equal_func, cond_func->arguments() + 1,
7532 1, usable_tables, sargables))
7533 return true;
7534 }
7535 }
7536 }
7537 }
7538
6/8
✓ Branch 0 taken 413648 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 413649 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 30199 times.
✓ Branch 5 taken 383450 times.
✓ Branch 6 taken 30199 times.
✓ Branch 7 taken 383450 times.
443847 if (is_local_field(cond_func->arguments()[1]) &&
7539
2/4
✓ Branch 0 taken 30199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30199 times.
✗ Branch 3 not taken.
30199 cond_func->functype() != Item_func::LIKE_FUNC) {
7540
2/4
✓ Branch 0 taken 30199 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30199 times.
60398 if (add_key_equal_fields(
7541 thd, key_fields, *and_level, cond_func,
7542
3/6
✓ Branch 0 taken 30199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30199 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 30199 times.
✗ Branch 5 not taken.
30199 (Item_field *)(cond_func->arguments()[1])->real_item(),
7543 equal_func, cond_func->arguments(), 1, usable_tables,
7544 sargables))
7545 return true;
7546 } else {
7547
2/4
✓ Branch 0 taken 383449 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383449 times.
✗ Branch 3 not taken.
383450 Item *real_item = cond_func->arguments()[1]->real_item();
7548
3/4
✓ Branch 0 taken 383449 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11147 times.
✓ Branch 3 taken 372302 times.
383449 if (real_item->type() == Item::FUNC_ITEM) {
7549 11147 Item_func *func_item = down_cast<Item_func *>(real_item);
7550
3/4
✓ Branch 0 taken 11147 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 91 times.
✓ Branch 3 taken 11056 times.
11147 if (func_item->functype() == Item_func::COLLATE_FUNC) {
7551
1/2
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
91 Item *key_item = func_item->key_item();
7552
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 54 times.
91 if (key_item->type() == Item::FIELD_ITEM) {
7553
3/6
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 37 times.
37 if (add_key_equal_fields(thd, key_fields, *and_level, cond_func,
7554 down_cast<Item_field *>(key_item),
7555 equal_func, cond_func->arguments(), 1,
7556 usable_tables, sargables))
7557 return true;
7558 }
7559 }
7560 }
7561 }
7562
7563 413648 break;
7564 }
7565 17266 case Item_func::OPTIMIZE_NULL:
7566 /* column_name IS [NOT] NULL */
7567
6/8
✓ Branch 0 taken 17266 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17266 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16284 times.
✓ Branch 5 taken 982 times.
✓ Branch 6 taken 16284 times.
✓ Branch 7 taken 982 times.
33550 if (is_local_field(cond_func->arguments()[0]) &&
7568
2/4
✓ Branch 0 taken 16284 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16284 times.
✗ Branch 3 not taken.
16284 !cond_func->is_outer_reference()) {
7569
2/4
✓ Branch 0 taken 16284 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16284 times.
✗ Branch 3 not taken.
16284 Item *tmp = new Item_null;
7570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16284 times.
16284 if (tmp == nullptr) return true;
7571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16284 times.
16284 if (add_key_equal_fields(
7572 thd, key_fields, *and_level, cond_func,
7573
2/4
✓ Branch 0 taken 16284 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16284 times.
✗ Branch 3 not taken.
16284 (Item_field *)(cond_func->arguments()[0])->real_item(),
7574
2/4
✓ Branch 0 taken 16284 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16284 times.
✗ Branch 3 not taken.
16284 cond_func->functype() == Item_func::ISNULL_FUNC, &tmp, 1,
7575 usable_tables, sargables))
7576 return true;
7577 }
7578 17266 break;
7579 3137157 case Item_func::OPTIMIZE_EQUAL:
7580 3137157 Item_equal *item_equal = (Item_equal *)cond;
7581 3137157 Item *const_item = item_equal->get_const();
7582
2/2
✓ Branch 0 taken 1227086 times.
✓ Branch 1 taken 1910061 times.
3137147 if (const_item) {
7583 /*
7584 For each field field1 from item_equal consider the equality
7585 field1=const_item as a condition allowing an index access of the table
7586 with field1 by the keys value of field1.
7587 */
7588
5/8
✓ Branch 0 taken 1227086 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1227096 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2569570 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1342475 times.
✓ Branch 7 taken 1227095 times.
2569560 for (Item_field &item : item_equal->get_fields()) {
7589
2/4
✓ Branch 0 taken 1342474 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1342474 times.
1342476 if (add_key_field(thd, key_fields, *and_level, cond_func, &item, true,
7590 &const_item, 1, usable_tables, sargables))
7591 return true;
7592 }
7593 } else {
7594 /*
7595 Consider all pairs of different fields included into item_equal.
7596 For each of them (field1, field1) consider the equality
7597 field1=field2 as a condition allowing an index access of the table
7598 with field1 by the keys value of field2.
7599 */
7600
5/8
✓ Branch 0 taken 1910068 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1910067 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5752785 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3842720 times.
✓ Branch 7 taken 1910065 times.
5752784 for (Item_field &outer : item_equal->get_fields()) {
7601
5/8
✓ Branch 0 taken 3842731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3842721 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12403482 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8560759 times.
✓ Branch 7 taken 3842723 times.
12403463 for (Item_field &inner : item_equal->get_fields()) {
7602
3/4
✓ Branch 0 taken 8560741 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4718038 times.
✓ Branch 3 taken 3842703 times.
8560760 if (!outer.field->eq(inner.field)) {
7603 4718038 Item *inner_ptr = &inner;
7604
2/4
✓ Branch 0 taken 4718037 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4718037 times.
4718038 if (add_key_field(thd, key_fields, *and_level, cond_func, &outer,
7605 true, &inner_ptr, 1, usable_tables, sargables))
7606 return true;
7607 }
7608 }
7609 }
7610 }
7611 3137160 break;
7612 }
7613 4931229 return false;
7614 }
7615
7616 /*
7617 Add all keys with uses 'field' for some keypart
7618 If field->and_level != and_level then only mark key_part as const_part
7619
7620 RETURN
7621 0 - OK
7622 1 - Out of memory.
7623 */
7624
7625 4828428 static bool add_key_part(Key_use_array *keyuse_array, Key_field *key_field) {
7626
3/4
✓ Branch 0 taken 4828430 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4828181 times.
✓ Branch 3 taken 249 times.
4828428 if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS)) {
7627 4828181 const Field *const field = key_field->item_field->field;
7628 4828181 TABLE_LIST *const tl = key_field->item_field->table_ref;
7629 4828181 TABLE *const table = tl->table;
7630
7631
2/2
✓ Branch 0 taken 17861920 times.
✓ Branch 1 taken 4828185 times.
22690105 for (uint key = 0; key < table->s->keys; key++) {
7632
2/2
✓ Branch 0 taken 25563 times.
✓ Branch 1 taken 17836360 times.
17861920 if (!(table->keys_in_use_for_query.is_set(key))) continue;
7633
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 17835838 times.
17836360 if (table->key_info[key].flags & (HA_FULLTEXT | HA_SPATIAL))
7634 522 continue; // ToDo: ft-keys in non-ft queries. SerG
7635
7636 17835838 uint key_parts = actual_key_parts(&table->key_info[key]);
7637
2/2
✓ Branch 0 taken 31205414 times.
✓ Branch 1 taken 17835839 times.
49041253 for (uint part = 0; part < key_parts; part++) {
7638
2/2
✓ Branch 0 taken 7130869 times.
✓ Branch 1 taken 24074582 times.
31205414 if (field->eq(table->key_info[key].key_part[part].field)) {
7639 const Key_use keyuse(tl, key_field->val,
7640 7130869 key_field->val->used_tables(), key, part,
7641 7130869 key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL,
7642 (key_part_map)1 << part,
7643 ~(ha_rows)0, // will be set in optimize_keyuse
7644 7130869 key_field->null_rejecting, key_field->cond_guard,
7645
1/2
✓ Branch 0 taken 7130827 times.
✗ Branch 1 not taken.
7130869 key_field->sj_pred_no);
7646
2/4
✓ Branch 0 taken 7130815 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7130815 times.
7130819 if (keyuse_array->push_back(keyuse))
7647 return true; /* purecov: inspected */
7648 }
7649 }
7650 }
7651 }
7652 4828432 return false;
7653 }
7654
7655 /**
7656 Function parses WHERE condition and add key_use for FT index
7657 into key_use array if suitable MATCH function is found.
7658 Condition should be a set of AND expression, OR is not supported.
7659 MATCH function should be a part of simple expression.
7660 Simple expression is MATCH only function or MATCH is a part of
7661 comparison expression ('>=' or '>' operations are supported).
7662 It also sets FT_HINTS values(op_type, op_value).
7663
7664 @param keyuse_array Key_use array
7665 @param cond WHERE condition
7666 @param usable_tables usable tables
7667 @param simple_match_expr true if this is the first call false otherwise.
7668 if MATCH function is found at first call it means
7669 that MATCH is simple expression, otherwise, in case
7670 of AND/OR condition this parameter will be false.
7671
7672 @retval
7673 true if FT key was added to Key_use array
7674 @retval
7675 false if no key was added to Key_use array
7676
7677 */
7678
7679 2465 static bool add_ft_keys(Key_use_array *keyuse_array, Item *cond,
7680 table_map usable_tables, bool simple_match_expr) {
7681 2465 Item_func_match *cond_func = nullptr;
7682
7683
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2457 times.
2465 if (!cond) return false;
7684
7685
2/4
✓ Branch 0 taken 2457 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2457 times.
2457 assert(cond->is_bool_func());
7686
7687
3/4
✓ Branch 0 taken 2457 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2336 times.
✓ Branch 3 taken 121 times.
2457 if (cond->type() == Item::FUNC_ITEM) {
7688 2336 Item_func *func = down_cast<Item_func *>(cond);
7689
1/2
✓ Branch 0 taken 2336 times.
✗ Branch 1 not taken.
2336 Item_func::Functype functype = func->functype();
7690
2/2
✓ Branch 0 taken 2153 times.
✓ Branch 1 taken 183 times.
2336 if (functype == Item_func::MATCH_FUNC) {
7691
1/2
✓ Branch 0 taken 2153 times.
✗ Branch 1 not taken.
2153 func = down_cast<Item_func *>(func->arguments()[0]);
7692
1/2
✓ Branch 0 taken 2153 times.
✗ Branch 1 not taken.
2153 functype = func->functype();
7693 }
7694 2336 enum ft_operation op_type = FT_OP_NO;
7695 2336 double op_value = 0.0;
7696
2/2
✓ Branch 0 taken 2153 times.
✓ Branch 1 taken 183 times.
2336 if (functype == Item_func::FT_FUNC) {
7697
1/2
✓ Branch 0 taken 2153 times.
✗ Branch 1 not taken.
2153 cond_func = down_cast<Item_func_match *>(func)->get_master();
7698 2153 cond_func->set_hints_op(op_type, op_value);
7699
2/2
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 90 times.
183 } else if (func->arg_count == 2) {
7700
1/2
✓ Branch 0 taken 93 times.
✗ Branch 1 not taken.
93 Item *arg0 = func->arguments()[0];
7701
1/2
✓ Branch 0 taken 93 times.
✗ Branch 1 not taken.
93 Item *arg1 = func->arguments()[1];
7702
10/12
✓ Branch 0 taken 93 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 65 times.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 17 times.
✓ Branch 7 taken 11 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 13 times.
✓ Branch 10 taken 15 times.
✓ Branch 11 taken 78 times.
110 if (arg1->const_item() && is_function_of_type(arg0, Item_func::FT_FUNC) &&
7703 4 ((functype == Item_func::GE_FUNC &&
7704
5/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 2 times.
17 (op_value = arg1->val_real()) > 0) ||
7705 13 (functype == Item_func::GT_FUNC &&
7706
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 (op_value = arg1->val_real()) >= 0))) {
7707
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 cond_func = down_cast<Item_func_match *>(arg0)->get_master();
7708
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13 times.
15 if (functype == Item_func::GE_FUNC)
7709 2 op_type = FT_OP_GE;
7710
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 else if (functype == Item_func::GT_FUNC)
7711 13 op_type = FT_OP_GT;
7712 15 cond_func->set_hints_op(op_type, op_value);
7713
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 } else if (arg0->const_item() &&
7714
9/10
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 55 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 8 times.
✓ Branch 9 taken 70 times.
88 is_function_of_type(arg1, Item_func::FT_FUNC) &&
7715 6 ((functype == Item_func::LE_FUNC &&
7716
5/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 2 times.
10 (op_value = arg0->val_real()) > 0) ||
7717 4 (functype == Item_func::LT_FUNC &&
7718
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 (op_value = arg0->val_real()) >= 0))) {
7719
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 cond_func = down_cast<Item_func_match *>(arg1)->get_master();
7720
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (functype == Item_func::LE_FUNC)
7721 4 op_type = FT_OP_GE;
7722
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 else if (functype == Item_func::LT_FUNC)
7723 4 op_type = FT_OP_GT;
7724 8 cond_func->set_hints_op(op_type, op_value);
7725 }
7726 }
7727
2/4
✓ Branch 0 taken 121 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 121 times.
✗ Branch 3 not taken.
121 } else if (cond->type() == Item::COND_ITEM) {
7728
1/2
✓ Branch 0 taken 121 times.
✗ Branch 1 not taken.
121 List_iterator_fast<Item> li(*down_cast<Item_cond *>(cond)->argument_list());
7729
7730
3/4
✓ Branch 0 taken 121 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 4 times.
121 if (down_cast<Item_cond *>(cond)->functype() == Item_func::COND_AND_FUNC) {
7731 Item *item;
7732
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 117 times.
370 while ((item = li++))
7733
2/4
✓ Branch 0 taken 253 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 253 times.
253 if (add_ft_keys(keyuse_array, item, usable_tables, false)) return true;
7734 }
7735 }
7736
7737
6/6
✓ Branch 0 taken 2176 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 2155 times.
✓ Branch 3 taken 21 times.
✓ Branch 4 taken 307 times.
✓ Branch 5 taken 2150 times.
4612 if (!cond_func || cond_func->key == NO_SUCH_KEY ||
7738
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2150 times.
2155 !(usable_tables & cond_func->table_ref->map()))
7739 307 return false;
7740
7741 2150 TABLE_LIST *tbl = cond_func->table_ref;
7742
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2148 times.
2150 if (!tbl->table->keys_in_use_for_query.is_set(cond_func->key)) return false;
7743
7744 2148 cond_func->set_simple_expression(simple_match_expr);
7745
7746 4296 const Key_use keyuse(tbl, cond_func, cond_func->key_item()->used_tables(),
7747 cond_func->key, FT_KEYPART,
7748 0, // optimize
7749 0, // keypart_map
7750 ~(ha_rows)0, // ref_table_rows
7751 false, // null_rejecting
7752 nullptr, // cond_guard
7753
1/2
✓ Branch 0 taken 2148 times.
✗ Branch 1 not taken.
2148 UINT_MAX); // sj_pred_no
7754 2148 tbl->table->reginfo.join_tab->keys().set_bit(cond_func->key);
7755
1/2
✓ Branch 0 taken 2148 times.
✗ Branch 1 not taken.
2148 return keyuse_array->push_back(keyuse);
7756 }
7757
7758 /**
7759 Compares two keyuse elements.
7760
7761 @param a first Key_use element
7762 @param b second Key_use element
7763
7764 Compare Key_use elements so that they are sorted as follows:
7765 -# By table.
7766 -# By key for each table.
7767 -# By keypart for each key.
7768 -# Const values.
7769 -# Ref_or_null.
7770
7771 @retval true If a < b.
7772 @retval false If a >= b.
7773 */
7774 34595261 static bool sort_keyuse(const Key_use &a, const Key_use &b) {
7775
2/2
✓ Branch 0 taken 21194410 times.
✓ Branch 1 taken 13400880 times.
34595261 if (a.table_ref->tableno() != b.table_ref->tableno())
7776 21194410 return a.table_ref->tableno() < b.table_ref->tableno();
7777
2/2
✓ Branch 0 taken 9352938 times.
✓ Branch 1 taken 4047942 times.
13400880 if (a.key != b.key) return a.key < b.key;
7778
2/2
✓ Branch 0 taken 1167849 times.
✓ Branch 1 taken 2880093 times.
4047942 if (a.keypart != b.keypart) return a.keypart < b.keypart;
7779 // Place const values before other ones
7780 2880093 bool a_const = a.used_tables & ~OUTER_REF_TABLE_BIT;
7781 2880093 bool b_const = b.used_tables & ~OUTER_REF_TABLE_BIT;
7782
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 2880006 times.
2880093 if (a_const != b_const) return b_const;
7783 /* Place rows that are not 'OPTIMIZE_REF_OR_NULL' first */
7784 2880006 return (a.optimize & KEY_OPTIMIZE_REF_OR_NULL) <
7785 2880006 (b.optimize & KEY_OPTIMIZE_REF_OR_NULL);
7786 }
7787
7788 /*
7789 Add to Key_field array all 'ref' access candidates within nested join.
7790
7791 This function populates Key_field array with entries generated from the
7792 ON condition of the given nested join, and does the same for nested joins
7793 contained within this nested join.
7794
7795 @param thd session context
7796 @param[in] nested_join_table Nested join pseudo-table to process
7797 @param[in,out] end End of the key field array
7798 @param[in,out] and_level And-level
7799 @param[in,out] sargables Array of found sargable candidates
7800
7801 @returns false if success, true if error
7802
7803 @note
7804 We can add accesses to the tables that are direct children of this nested
7805 join (1), and are not inner tables w.r.t their neighbours (2).
7806
7807 Example for #1 (outer brackets pair denotes nested join this function is
7808 invoked for):
7809 @code
7810 ... LEFT JOIN (t1 LEFT JOIN (t2 ... ) ) ON cond
7811 @endcode
7812 Example for #2:
7813 @code
7814 ... LEFT JOIN (t1 LEFT JOIN t2 ) ON cond
7815 @endcode
7816 In examples 1-2 for condition cond, we can add 'ref' access candidates to
7817 t1 only.
7818 Example #3:
7819 @code
7820 ... LEFT JOIN (t1, t2 LEFT JOIN t3 ON inner_cond) ON cond
7821 @endcode
7822 Here we can add 'ref' access candidates for t1 and t2, but not for t3.
7823 */
7824
7825 6092 static bool add_key_fields_for_nj(THD *thd, JOIN *join,
7826 TABLE_LIST *nested_join_table,
7827 Key_field **end, uint *and_level,
7828 SARGABLE_PARAM **sargables) {
7829 6092 mem_root_deque<TABLE_LIST *> &join_list =
7830 6092 nested_join_table->nested_join->join_list;
7831
1/2
✓ Branch 0 taken 6092 times.
✗ Branch 1 not taken.
6092 auto li = join_list.begin();
7832
1/2
✓ Branch 0 taken 6092 times.
✗ Branch 1 not taken.
6092 auto li_end = join_list.end();
7833
1/2
✓ Branch 0 taken 6092 times.
✗ Branch 1 not taken.
6092 auto li2 = join_list.begin();
7834
1/2
✓ Branch 0 taken 6092 times.
✗ Branch 1 not taken.
6092 auto li2_end = join_list.end();
7835 6092 bool have_another = false;
7836 6092 table_map tables = 0;
7837 TABLE_LIST *table;
7838
7839
9/12
✓ Branch 0 taken 21846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15729 times.
✓ Branch 3 taken 6117 times.
✓ Branch 4 taken 15729 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15729 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6117 times.
✓ Branch 9 taken 15729 times.
✓ Branch 10 taken 25 times.
✓ Branch 11 taken 6092 times.
21871 while ((table = (li != li_end) ? *li++ : nullptr) ||
7840
3/6
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
25 (have_another && li2 != join_list.end() &&
7841 25 (li = li2, li_end = li2_end, have_another = false,
7842
7/12
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 25 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 25 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 15754 times.
✓ Branch 11 taken 6092 times.
21871 (li != li_end) && (table = *li++)))) {
7843
2/2
✓ Branch 0 taken 158 times.
✓ Branch 1 taken 15596 times.
15754 if (table->nested_join) {
7844
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 133 times.
158 if (!table->join_cond_optim()) {
7845 /* It's a semi-join nest. Walk into it as if it wasn't a nest */
7846 25 have_another = true;
7847 25 li2 = li;
7848 25 li2_end = li_end;
7849
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 li = table->nested_join->join_list.begin();
7850
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 li_end = table->nested_join->join_list.end();
7851 } else {
7852
2/4
✓ Branch 0 taken 133 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 133 times.
133 if (add_key_fields_for_nj(thd, join, table, end, and_level, sargables))
7853 return true;
7854 }
7855
2/2
✓ Branch 0 taken 11391 times.
✓ Branch 1 taken 4205 times.
15596 } else if (!table->join_cond_optim())
7856 11391 tables |= table->map();
7857 }
7858
2/2
✓ Branch 0 taken 1852 times.
✓ Branch 1 taken 4240 times.
6092 if (nested_join_table->join_cond_optim()) {
7859
2/4
✓ Branch 0 taken 1852 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1852 times.
1852 if (add_key_fields(thd, join, end, and_level,
7860 nested_join_table->join_cond_optim(), tables, sargables))
7861 return true;
7862 }
7863 6092 return false;
7864 }
7865
7866 /// @} (end of group RefOptimizerModule)
7867
7868 /**
7869 Check for the presence of AGGFN(DISTINCT a) queries that may be subject
7870 to loose index scan.
7871
7872
7873 Check if the query is a subject to AGGFN(DISTINCT) using loose index scan
7874 (GroupIndexSkipScanIterator).
7875 Optionally (if out_args is supplied) will push the arguments of
7876 AGGFN(DISTINCT) to the list
7877
7878 Check for every COUNT(DISTINCT), AVG(DISTINCT) or
7879 SUM(DISTINCT). These can be resolved by Loose Index Scan as long
7880 as all the aggregate distinct functions refer to the same
7881 fields. Thus:
7882
7883 SELECT AGGFN(DISTINCT a, b), AGGFN(DISTINCT b, a)... => can use LIS
7884 SELECT AGGFN(DISTINCT a), AGGFN(DISTINCT a) ... => can use LIS
7885 SELECT AGGFN(DISTINCT a, b), AGGFN(DISTINCT a) ... => cannot use LIS
7886 SELECT AGGFN(DISTINCT a), AGGFN(DISTINCT b) ... => cannot use LIS
7887 etc.
7888
7889 @param join the join to check
7890 @param[out] out_args Collect the arguments of the aggregate functions
7891 to a list. We don't worry about duplicates as
7892 these will be sorted out later in
7893 get_best_group_min_max.
7894
7895 @return does the query qualify for indexed AGGFN(DISTINCT)
7896 @retval true it does
7897 @retval false AGGFN(DISTINCT) must apply distinct in it.
7898 */
7899
7900 2822214 bool is_indexed_agg_distinct(JOIN *join,
7901 mem_root_deque<Item_field *> *out_args) {
7902 Item_sum **sum_item_ptr;
7903 2822214 bool result = false;
7904
1/2
✓ Branch 0 taken 2822232 times.
✗ Branch 1 not taken.
2822214 Field_map first_aggdistinct_fields;
7905
7906
2/2
✓ Branch 0 taken 2282923 times.
✓ Branch 1 taken 539309 times.
2822232 if (join->primary_tables > 1 || /* reference more than 1 table */
7907
2/2
✓ Branch 0 taken 2280160 times.
✓ Branch 1 taken 2763 times.
2282923 join->select_distinct || /* or a DISTINCT */
7908
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2280159 times.
2280160 join->query_block->olap == ROLLUP_TYPE) /* Check (B3) for ROLLUP */
7909 542073 return false;
7910
7911
2/4
✓ Branch 0 taken 2280159 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2280159 times.
2280159 if (join->make_sum_func_list(*join->fields, true)) return false;
7912
7913
2/2
✓ Branch 0 taken 863478 times.
✓ Branch 1 taken 1432650 times.
2296128 for (sum_item_ptr = join->sum_funcs; *sum_item_ptr; sum_item_ptr++) {
7914 863478 Item_sum *sum_item = *sum_item_ptr;
7915
1/2
✓ Branch 0 taken 863478 times.
✗ Branch 1 not taken.
863478 Field_map cur_aggdistinct_fields;
7916 Item *expr;
7917 /* aggregate is not AGGFN(DISTINCT) or more than 1 argument to it */
7918
5/6
✓ Branch 0 taken 863478 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14673 times.
✓ Branch 3 taken 1131 times.
✓ Branch 4 taken 354 times.
✓ Branch 5 taken 847320 times.
863478 switch (sum_item->sum_func()) {
7919 14673 case Item_sum::MIN_FUNC:
7920 case Item_sum::MAX_FUNC:
7921 14673 continue;
7922 1131 case Item_sum::COUNT_DISTINCT_FUNC:
7923 1131 break;
7924 354 case Item_sum::AVG_DISTINCT_FUNC:
7925 case Item_sum::SUM_DISTINCT_FUNC:
7926
2/4
✓ Branch 0 taken 354 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 354 times.
✗ Branch 3 not taken.
354 if (sum_item->argument_count() == 1) break;
7927 [[fallthrough]];
7928 default:
7929 847509 return false;
7930 }
7931
7932
3/4
✓ Branch 0 taken 3062 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1734 times.
✓ Branch 3 taken 1328 times.
3062 for (uint i = 0; i < sum_item->argument_count(); i++) {
7933
1/2
✓ Branch 0 taken 1734 times.
✗ Branch 1 not taken.
1734 expr = sum_item->get_arg(i);
7934 /* The AGGFN(DISTINCT) arg is not an attribute? */
7935
4/6
✓ Branch 0 taken 1734 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1734 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 157 times.
✓ Branch 5 taken 1577 times.
1734 if (expr->real_item()->type() != Item::FIELD_ITEM) return false;
7936
7937
1/2
✓ Branch 0 taken 1577 times.
✗ Branch 1 not taken.
1577 Item_field *item = static_cast<Item_field *>(expr->real_item());
7938
3/4
✓ Branch 0 taken 994 times.
✓ Branch 1 taken 583 times.
✓ Branch 2 taken 994 times.
✗ Branch 3 not taken.
1577 if (out_args) out_args->push_back(item);
7939
7940 1577 cur_aggdistinct_fields.set_bit(item->field->field_index());
7941 1577 result = true;
7942 }
7943 /*
7944 If there are multiple aggregate functions, make sure that they all
7945 refer to exactly the same set of columns.
7946 */
7947
3/4
✓ Branch 0 taken 1328 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1078 times.
✓ Branch 3 taken 250 times.
1328 if (first_aggdistinct_fields.is_clear_all())
7948
1/2
✓ Branch 0 taken 1078 times.
✗ Branch 1 not taken.
1078 first_aggdistinct_fields.merge(cur_aggdistinct_fields);
7949
3/4
✓ Branch 0 taken 250 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 218 times.
250 else if (first_aggdistinct_fields != cur_aggdistinct_fields)
7950 32 return false;
7951 }
7952
7953 1432650 return result;
7954 }
7955
7956 /**
7957 Print keys that were appended to join_tab->const_keys because they
7958 can be used for GROUP BY or DISTINCT to the optimizer trace.
7959
7960 @param trace The optimizer trace context we're adding info to
7961 @param join_tab The table the indexes cover
7962 @param new_keys The keys that are considered useful because they can
7963 be used for GROUP BY or DISTINCT
7964 @param cause Zero-terminated string with reason for adding indexes
7965 to const_keys
7966
7967 @see add_group_and_distinct_keys()
7968 */
7969 2484 static void trace_indexes_added_group_distinct(Opt_trace_context *trace,
7970 const JOIN_TAB *join_tab,
7971 const Key_map new_keys,
7972 const char *cause) {
7973
2/2
✓ Branch 0 taken 2401 times.
✓ Branch 1 taken 83 times.
2484 if (likely(!trace->is_started())) return;
7974
7975 83 KEY *key_info = join_tab->table()->key_info;
7976 83 Key_map existing_keys = join_tab->const_keys;
7977 83 uint nbrkeys = join_tab->table()->s->keys;
7978
7979
1/2
✓ Branch 0 taken 83 times.
✗ Branch 1 not taken.
83 Opt_trace_object trace_summary(trace, "const_keys_added");
7980 {
7981
1/2
✓ Branch 0 taken 83 times.
✗ Branch 1 not taken.
83 Opt_trace_array trace_key(trace, "keys");
7982
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 83 times.
208 for (uint j = 0; j < nbrkeys; j++)
7983
6/6
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 110 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 110 times.
✓ Branch 5 taken 15 times.
125 if (new_keys.is_set(j) && !existing_keys.is_set(j))
7984
1/2
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
110 trace_key.add_utf8(key_info[j].name);
7985 83 }
7986
1/2
✓ Branch 0 taken 83 times.
✗ Branch 1 not taken.
83 trace_summary.add_alnum("cause", cause);
7987 83 }
7988
7989 /**
7990 Discover the indexes that might be used for GROUP BY or DISTINCT queries or
7991 indexes that might be used for SKIP SCAN.
7992
7993 If the query has a GROUP BY clause, find all indexes that contain
7994 all GROUP BY fields, and add those indexes to join_tab->const_keys
7995 and join_tab->keys.
7996
7997 If the query has a DISTINCT clause, find all indexes that contain
7998 all SELECT fields, and add those indexes to join_tab->const_keys and
7999 join_tab->keys. This allows later on such queries to be processed by
8000 a GroupIndexSkipScanIterator.
8001
8002 If the query does not have GROUP BY clause or any aggregate function
8003 the function collects possible keys to use for skip scan access.
8004
8005 Note that indexes that are not usable for resolving GROUP
8006 BY/DISTINCT may also be added in some corner cases. For example, an
8007 index covering 'a' and 'b' is not usable for the following query but
8008 is still added: "SELECT DISTINCT a+b FROM t1". This is not a big
8009 issue because a) although the optimizer will consider using the
8010 index, it will not chose it (so minor calculation cost added but not
8011 wrong result) and b) it applies only to corner cases.
8012
8013 @param join the current join
8014 @param join_tab joined table
8015 */
8016
8017 3828598 static void add_loose_index_scan_and_skip_scan_keys(JOIN *join,
8018 JOIN_TAB *join_tab) {
8019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3828616 times.
3828598 assert(join_tab->const_keys.is_subset(join_tab->keys()));
8020
8021 3828616 mem_root_deque<Item_field *> indexed_fields(join->thd->mem_root);
8022 ORDER *cur_group;
8023 const char *cause;
8024
8025 /* Find the indexes that might be used for skip scan queries. */
8026
1/2
✓ Branch 0 taken 3828600 times.
✗ Branch 1 not taken.
3828601 if (hint_table_state(join->thd, join_tab->table_ref, SKIP_SCAN_HINT_ENUM,
8027 3817398 OPTIMIZER_SKIP_SCAN) &&
8028
6/6
✓ Branch 0 taken 3201302 times.
✓ Branch 1 taken 616096 times.
✓ Branch 2 taken 767315 times.
✓ Branch 3 taken 2433987 times.
✓ Branch 4 taken 762689 times.
✓ Branch 5 taken 4626 times.
4584713 join->where_cond && join->primary_tables == 1 &&
8029 767315 join->group_list.empty() &&
8030
7/8
✓ Branch 0 taken 3817398 times.
✓ Branch 1 taken 11202 times.
✓ Branch 2 taken 762691 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 762561 times.
✓ Branch 5 taken 130 times.
✓ Branch 6 taken 761024 times.
✓ Branch 7 taken 3067578 times.
8408559 !is_indexed_agg_distinct(join, &indexed_fields) &&
8031
2/2
✓ Branch 0 taken 761024 times.
✓ Branch 1 taken 1537 times.
762561 !join->select_distinct) {
8032
1/2
✓ Branch 0 taken 761024 times.
✗ Branch 1 not taken.
761024 join->where_cond->walk(&Item::collect_item_field_processor,
8033 enum_walk::POSTFIX, (uchar *)&indexed_fields);
8034
1/2
✓ Branch 0 taken 761024 times.
✗ Branch 1 not taken.
761024 Key_map possible_keys;
8035 761024 possible_keys.set_all();
8036 761024 join_tab->skip_scan_keys.clear_all();
8037
7/12
✓ Branch 0 taken 761024 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 761024 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1270773 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1269107 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2030131 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1270773 times.
✓ Branch 11 taken 759358 times.
2030131 for (Item_field *cur_item : indexed_fields) {
8038
3/4
✓ Branch 0 taken 1270773 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1666 times.
✓ Branch 3 taken 1269107 times.
1270773 if (cur_item->used_tables() != join_tab->table_ref->map()) return;
8039 1269107 possible_keys.intersect(cur_item->field->part_of_key);
8040 }
8041 759358 join_tab->skip_scan_keys.merge(possible_keys);
8042 759358 cause = "skip_scan";
8043 759358 return;
8044 }
8045
8046
2/2
✓ Branch 0 taken 20167 times.
✓ Branch 1 taken 3047411 times.
3067578 if (!join->group_list.empty()) {
8047 /* Collect all query fields referenced in the GROUP clause. */
8048
2/2
✓ Branch 0 taken 46761 times.
✓ Branch 1 taken 20167 times.
66928 for (cur_group = join->group_list.order; cur_group;
8049 46761 cur_group = cur_group->next)
8050 46761 (*cur_group->item)
8051
1/2
✓ Branch 0 taken 46761 times.
✗ Branch 1 not taken.
46761 ->walk(&Item::collect_item_field_processor, enum_walk::POSTFIX,
8052 (uchar *)&indexed_fields);
8053 20167 cause = "group_by";
8054
2/2
✓ Branch 0 taken 8191 times.
✓ Branch 1 taken 3039220 times.
3047411 } else if (join->select_distinct) {
8055 /* Collect all query fields referenced in the SELECT clause. */
8056
8/14
✓ Branch 0 taken 8191 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8191 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8191 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 31799 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 31799 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 39990 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 31799 times.
✓ Branch 13 taken 8191 times.
39990 for (Item *item : VisibleFields(*join->fields)) {
8057
1/2
✓ Branch 0 taken 31799 times.
✗ Branch 1 not taken.
31799 item->walk(&Item::collect_item_field_processor, enum_walk::POSTFIX,
8058 (uchar *)&indexed_fields);
8059 }
8060 8191 cause = "distinct";
8061
4/4
✓ Branch 0 taken 395984 times.
✓ Branch 1 taken 2643236 times.
✓ Branch 2 taken 272 times.
✓ Branch 3 taken 3038948 times.
3435204 } else if (join->tmp_table_param.sum_func_count &&
8062
3/4
✓ Branch 0 taken 395984 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 272 times.
✓ Branch 3 taken 395712 times.
395984 is_indexed_agg_distinct(join, &indexed_fields)) {
8063 /*
8064 SELECT list with AGGFN(distinct col). The query qualifies for
8065 loose index scan, and is_indexed_agg_distinct() has already
8066 collected all referenced fields into indexed_fields.
8067 */
8068 272 join->streaming_aggregation = true;
8069 272 cause = "indexed_distinct_aggregate";
8070 } else
8071 3038948 return;
8072
8073
3/4
✓ Branch 0 taken 28630 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 229 times.
✓ Branch 3 taken 28401 times.
28630 if (indexed_fields.empty()) return;
8074
8075 28401 Key_map possible_keys = join_tab->table()->keys_in_use_for_query;
8076 28401 possible_keys.merge(join_tab->table()->keys_in_use_for_group_by);
8077
8078 /* Intersect the keys of all group fields. */
8079
7/12
✓ Branch 0 taken 28401 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28401 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 37157 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 21686 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 50087 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 37157 times.
✓ Branch 11 taken 12930 times.
50087 for (Item_field *cur_item : indexed_fields) {
8080
3/4
✓ Branch 0 taken 37157 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15471 times.
✓ Branch 3 taken 21686 times.
37157 if (cur_item->used_tables() != join_tab->table_ref->map()) {
8081 /*
8082 Doing GROUP BY or DISTINCT on a field in another table so no
8083 index in this table is usable
8084 */
8085 15471 return;
8086 } else
8087 21686 possible_keys.intersect(cur_item->field->part_of_key);
8088 }
8089
8090 /*
8091 At this point, possible_keys has key bits set only for usable
8092 indexes because indexed_fields is non-empty and if any of the
8093 fields belong to a different table the function would exit in the
8094 loop above.
8095 */
8096
8097
4/4
✓ Branch 0 taken 3404 times.
✓ Branch 1 taken 9526 times.
✓ Branch 2 taken 2484 times.
✓ Branch 3 taken 10446 times.
16334 if (!possible_keys.is_clear_all() &&
8098
2/2
✓ Branch 0 taken 2484 times.
✓ Branch 1 taken 920 times.
3404 !possible_keys.is_subset(join_tab->const_keys)) {
8099
1/2
✓ Branch 0 taken 2484 times.
✗ Branch 1 not taken.
2484 trace_indexes_added_group_distinct(&join->thd->opt_trace, join_tab,
8100 possible_keys, cause);
8101 2484 join_tab->const_keys.merge(possible_keys);
8102 2484 join_tab->keys().merge(possible_keys);
8103 }
8104
8105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12930 times.
12930 assert(join_tab->const_keys.is_subset(join_tab->keys()));
8106
2/2
✓ Branch 0 taken 12930 times.
✓ Branch 1 taken 3815674 times.
3828602 }
8107
8108 /**
8109 Update keyuse array with all possible keys we can use to fetch rows.
8110
8111 @param thd session context
8112 @param[out] keyuse Put here ordered array of Key_use structures
8113 @param join_tab Array in table number order
8114 @param tables Number of tables in join
8115 @param cond WHERE condition (note that the function analyzes
8116 join_tab[i]->join_cond() too)
8117 @param normal_tables Tables not inner w.r.t some outer join (ones
8118 for which we can make ref access based the WHERE
8119 clause)
8120 @param query_block current SELECT
8121 @param[out] sargables Array of found sargable candidates
8122
8123 @returns false if success, true if error
8124 */
8125
8126 1309281 static bool update_ref_and_keys(THD *thd, Key_use_array *keyuse,
8127 JOIN_TAB *join_tab, uint tables, Item *cond,
8128 table_map normal_tables,
8129 Query_block *query_block,
8130 SARGABLE_PARAM **sargables) {
8131
4/6
✓ Branch 0 taken 1305192 times.
✓ Branch 1 taken 4089 times.
✓ Branch 2 taken 1305203 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1305203 times.
1309281 assert(cond == nullptr || cond->is_bool_func());
8132 uint and_level, i;
8133 Key_field *key_fields, *end, *field;
8134 size_t sz;
8135 1309292 uint m = max(query_block->max_equal_elems, 1U);
8136 1309289 JOIN *const join = query_block->join;
8137 /*
8138 We use the same piece of memory to store both Key_field
8139 and SARGABLE_PARAM structure.
8140 Key_field values are placed at the beginning this memory
8141 while SARGABLE_PARAM values are put at the end.
8142 All predicates that are used to fill arrays of Key_field
8143 and SARGABLE_PARAM structures have at most 2 arguments
8144 except BETWEEN predicates that have 3 arguments and
8145 IN predicates.
8146 This any predicate if it's not BETWEEN/IN can be used
8147 directly to fill at most 2 array elements, either of Key_field
8148 or SARGABLE_PARAM type. For a BETWEEN predicate 3 elements
8149 can be filled as this predicate is considered as
8150 saragable with respect to each of its argument.
8151 An IN predicate can require at most 1 element as currently
8152 it is considered as sargable only for its first argument.
8153 Multiple equality can add elements that are filled after
8154 substitution of field arguments by equal fields. There
8155 can be not more than query_block->max_equal_elems such
8156 substitutions.
8157 */
8158 1309289 sz = max(sizeof(Key_field), sizeof(SARGABLE_PARAM)) *
8159 1309285 (((query_block->cond_count + 1) * 2 + query_block->between_count) * m +
8160 1);
8161
2/4
✓ Branch 0 taken 1309292 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1309292 times.
1309285 if (!(key_fields = (Key_field *)thd->alloc(sz)))
8162 return true; /* purecov: inspected */
8163 1309292 and_level = 0;
8164 1309292 field = end = key_fields;
8165 1309292 *sargables = (SARGABLE_PARAM *)key_fields +
8166 1309292 (sz - sizeof((*sargables)[0].field)) / sizeof(SARGABLE_PARAM);
8167 /* set a barrier for the array of SARGABLE_PARAM */
8168 1309292 (*sargables)[0].field = nullptr;
8169
8170
2/2
✓ Branch 0 taken 1305206 times.
✓ Branch 1 taken 4086 times.
1309292 if (cond) {
8171
2/4
✓ Branch 0 taken 1305206 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1305206 times.
1305206 if (add_key_fields(thd, join, &end, &and_level, cond, normal_tables,
8172 sargables))
8173 return true;
8174
8175 // The relevant secondary engines don't support antijoin, so don't enable
8176 // this optimization for them.
8177
2/2
✓ Branch 0 taken 1305086 times.
✓ Branch 1 taken 119 times.
1305206 if (thd->secondary_engine_optimization() !=
8178 Secondary_engine_optimization::SECONDARY) {
8179
2/2
✓ Branch 0 taken 4312307 times.
✓ Branch 1 taken 1305083 times.
5617390 for (Key_field *fld = field; fld != end; fld++) {
8180 /* Mark that we can optimize LEFT JOIN */
8181
5/6
✓ Branch 0 taken 4312304 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2633 times.
✓ Branch 3 taken 4309671 times.
✓ Branch 4 taken 361 times.
✓ Branch 5 taken 4311943 times.
4314940 if (fld->val->type() == Item::NULL_ITEM &&
8182
2/2
✓ Branch 0 taken 361 times.
✓ Branch 1 taken 2272 times.
2633 !fld->item_field->field->is_nullable()) {
8183 /*
8184 Example:
8185 SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.a IS NULL;
8186 this just wants rows of t1 where t1.a does not exist in t2.
8187 */
8188 361 fld->item_field->field->table->reginfo.not_exists_optimize = true;
8189 }
8190 }
8191 }
8192 }
8193
8194
2/2
✓ Branch 0 taken 3312263 times.
✓ Branch 1 taken 1309289 times.
4621552 for (i = 0; i < tables; i++) {
8195 /*
8196 Block the creation of keys for inner tables of outer joins.
8197 Here only the outer joins that can not be converted to
8198 inner joins are left and all nests that can be eliminated
8199 are flattened.
8200 In the future when we introduce conditional accesses
8201 for inner tables in outer joins these keys will be taken
8202 into account as well.
8203 */
8204
2/2
✓ Branch 0 taken 401940 times.
✓ Branch 1 taken 2910321 times.
3312263 if (join_tab[i].join_cond()) {
8205
2/4
✓ Branch 0 taken 401943 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 401943 times.
401942 if (add_key_fields(thd, join, &end, &and_level, join_tab[i].join_cond(),
8206 401940 join_tab[i].table_ref->map(), sargables))
8207 return true;
8208 }
8209 }
8210
8211 /* Process ON conditions for the nested joins */
8212
7/12
✓ Branch 0 taken 1309295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1309295 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3302623 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3302632 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4611920 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3302625 times.
✓ Branch 11 taken 1309295 times.
4611912 for (TABLE_LIST *tl : query_block->top_join_list) {
8213
3/4
✓ Branch 0 taken 5959 times.
✓ Branch 1 taken 3296664 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3302623 times.
3308582 if (tl->nested_join &&
8214
2/4
✓ Branch 0 taken 5959 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5959 times.
5959 add_key_fields_for_nj(thd, join, tl, &end, &and_level, sargables))
8215 return true;
8216 }
8217
8218 /* Generate keys descriptions for derived tables */
8219
2/2
✓ Branch 0 taken 3011 times.
✓ Branch 1 taken 1306284 times.
1309295 if (query_block->materialized_derived_table_count) {
8220
2/4
✓ Branch 0 taken 3011 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3011 times.
3011 if (join->generate_derived_keys()) return true;
8221 }
8222 /* fill keyuse with found key parts */
8223
2/2
✓ Branch 0 taken 4827492 times.
✓ Branch 1 taken 1309298 times.
6136790 for (; field != end; field++) {
8224
2/4
✓ Branch 0 taken 4827495 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4827495 times.
4827492 if (add_key_part(keyuse, field)) return true;
8225 }
8226
8227
2/2
✓ Branch 0 taken 2212 times.
✓ Branch 1 taken 1307086 times.
1309298 if (query_block->ftfunc_list->elements) {
8228
2/4
✓ Branch 0 taken 2212 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2212 times.
2212 if (add_ft_keys(keyuse, cond, normal_tables, true)) return true;
8229 }
8230
8231 /*
8232 Sort the array of possible keys and remove the following key parts:
8233 - ref if there is a keypart which is a ref and a const.
8234 (e.g. if there is a key(a,b) and the clause is a=3 and b=7 and b=t2.d,
8235 then we skip the key part corresponding to b=t2.d)
8236 - keyparts without previous keyparts
8237 (e.g. if there is a key(a,b,c) but only b < 5 (or a=2 and c < 3) is
8238 used in the query, we drop the partial key parts from consideration).
8239 Special treatment for ft-keys.
8240 */
8241
3/4
✓ Branch 0 taken 1309289 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 689968 times.
✓ Branch 3 taken 619321 times.
1309298 if (!keyuse->empty()) {
8242 Key_use *save_pos, *use;
8243
8244
1/2
✓ Branch 0 taken 689970 times.
✗ Branch 1 not taken.
689968 std::sort(keyuse->begin(), keyuse->begin() + keyuse->size(), sort_keyuse);
8245
8246 const Key_use key_end(nullptr, nullptr, 0, 0, 0, 0, 0, 0, false, nullptr,
8247 689970 0);
8248
2/4
✓ Branch 0 taken 689961 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 689961 times.
689968 if (keyuse->push_back(key_end)) // added for easy testing
8249 return true;
8250
8251 689961 use = save_pos = keyuse->begin();
8252 689963 const Key_use *prev = &key_end;
8253 689963 bool found_eq_constant = false;
8254
2/2
✓ Branch 0 taken 7132012 times.
✓ Branch 1 taken 689943 times.
7821975 for (i = 0; i < keyuse->size() - 1; i++, use++) {
8255 7132012 TABLE *const table = use->table_ref->table;
8256
5/6
✓ Branch 0 taken 7132028 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1015013 times.
✓ Branch 3 taken 6117015 times.
✓ Branch 4 taken 1014805 times.
✓ Branch 5 taken 6117223 times.
8147025 if (use->val->const_for_execution() &&
8257
2/2
✓ Branch 0 taken 1014805 times.
✓ Branch 1 taken 208 times.
1015013 use->optimize != KEY_OPTIMIZE_REF_OR_NULL)
8258 1014805 table->const_key_parts[use->key] |= use->keypart_map;
8259
2/2
✓ Branch 0 taken 7129884 times.
✓ Branch 1 taken 2144 times.
7132028 if (use->keypart != FT_KEYPART) {
8260
4/4
✓ Branch 0 taken 2475035 times.
✓ Branch 1 taken 4654849 times.
✓ Branch 2 taken 1298376 times.
✓ Branch 3 taken 1176659 times.
7129884 if (use->key == prev->key && use->table_ref == prev->table_ref) {
8261
2/2
✓ Branch 0 taken 1297863 times.
✓ Branch 1 taken 513 times.
1298376 if (prev->keypart + 1 < use->keypart ||
8262
4/4
✓ Branch 0 taken 408495 times.
✓ Branch 1 taken 889368 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 408411 times.
1297863 (prev->keypart == use->keypart && found_eq_constant))
8263 597 continue; /* remove */
8264
2/2
✓ Branch 0 taken 1957984 times.
✓ Branch 1 taken 3873524 times.
5831508 } else if (use->keypart != 0) // First found must be 0
8265 1957984 continue;
8266 }
8267
8268 /*
8269 Protect against self assignment.
8270 The compiler *may* generate a call to memcpy() to do the assignment,
8271 and that is undefined behaviour (memory overlap).
8272 */
8273
2/2
✓ Branch 0 taken 2618726 times.
✓ Branch 1 taken 2554721 times.
5173447 if (save_pos != use) *save_pos = *use;
8274 5173447 prev = use;
8275
1/2
✓ Branch 0 taken 5173443 times.
✗ Branch 1 not taken.
5173447 found_eq_constant = use->val->const_for_execution();
8276 /* Save ptr to first use */
8277
2/2
✓ Branch 0 taken 2591227 times.
✓ Branch 1 taken 2582216 times.
5173443 if (!table->reginfo.join_tab->keyuse())
8278 2591227 table->reginfo.join_tab->set_keyuse(save_pos);
8279 5173442 table->reginfo.join_tab->checked_keys.set_bit(use->key);
8280 5173431 save_pos++;
8281 }
8282 689943 i = (uint)(save_pos - keyuse->begin());
8283 689970 keyuse->at(i) = key_end;
8284 689969 keyuse->chop(i);
8285 }
8286
1/2
✓ Branch 0 taken 1309289 times.
✗ Branch 1 not taken.
1309290 print_keyuse_array(thd, &thd->opt_trace, keyuse);
8287 /*
8288 Number of functions here call val_x() methods, which might throw an error.
8289 Catch those errors here.
8290 */
8291
1/2
✓ Branch 0 taken 1309294 times.
✗ Branch 1 not taken.
1309289 return thd->is_error();
8292 }
8293
8294 /**
8295 Create a keyuse array for a table with a primary key.
8296 To be used when creating a materialized temporary table.
8297
8298 @param thd THD pointer, for memory allocation
8299 @param keyparts Number of key parts in the primary key
8300 @param fields fields
8301 @param outer_exprs List of items used for key lookup
8302
8303 @return Pointer to created keyuse array, or NULL if error
8304 */
8305 934 Key_use_array *create_keyuse_for_table(
8306 THD *thd, uint keyparts, Item_field **fields,
8307 const mem_root_deque<Item *> &outer_exprs) {
8308
1/2
✓ Branch 0 taken 934 times.
✗ Branch 1 not taken.
934 void *mem = thd->alloc(sizeof(Key_use_array));
8309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 934 times.
934 if (!mem) return nullptr;
8310
1/2
✓ Branch 0 taken 934 times.
✗ Branch 1 not taken.
934 Key_use_array *keyuses = new (mem) Key_use_array(thd->mem_root);
8311
8312
1/2
✓ Branch 0 taken 934 times.
✗ Branch 1 not taken.
934 auto outer_expr_it = outer_exprs.begin();
8313
8314
2/2
✓ Branch 0 taken 945 times.
✓ Branch 1 taken 934 times.
1879 for (uint keypartno = 0; keypartno < keyparts; keypartno++) {
8315
2/4
✓ Branch 0 taken 945 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 945 times.
✗ Branch 3 not taken.
945 Item *const item = *outer_expr_it++;
8316 945 Key_field key_field(fields[keypartno], item, 0, 0, true,
8317 // null_rejecting must be true for field items only,
8318 // add_not_null_conds() is incapable of handling
8319 // other item types.
8320
1/2
✓ Branch 0 taken 945 times.
✗ Branch 1 not taken.
945 (item->type() == Item::FIELD_ITEM), nullptr, UINT_MAX);
8321
2/4
✓ Branch 0 taken 945 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 945 times.
945 if (add_key_part(keyuses, &key_field)) return nullptr;
8322 }
8323 934 const Key_use key_end(nullptr, nullptr, 0, 0, 0, 0, 0, 0, false, nullptr, 0);
8324
2/4
✓ Branch 0 taken 934 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 934 times.
934 if (keyuses->push_back(key_end)) // added for easy testing
8325 return nullptr;
8326
8327 934 return keyuses;
8328 }
8329
8330 /**
8331 Move const tables first in the position array.
8332
8333 Increment the number of const tables and set same basic properties for the
8334 const table.
8335 A const table looked up by a key has type JT_CONST.
8336 A const table with a single row has type JT_SYSTEM.
8337
8338 @param tab Table that is designated as a const table
8339 @param key The key definition to use for this table (NULL if table scan)
8340 */
8341
8342 101053 void JOIN::mark_const_table(JOIN_TAB *tab, Key_use *key) {
8343 101053 POSITION *const position = positions + const_tables;
8344 101053 position->table = tab;
8345 101053 position->key = key;
8346 101053 position->rows_fetched = 1.0; // This is a const table
8347 101053 position->filter_effect = 1.0;
8348 101053 position->prefix_rowcount = 1.0;
8349 101053 position->read_cost = 0.0;
8350 101053 position->ref_depend_map = 0;
8351 101053 position->loosescan_key = MAX_KEY; // Not a LooseScan
8352 101053 position->sj_strategy = SJ_OPT_NONE;
8353 101053 positions->use_join_buffer = false;
8354
8355 // Move the const table as far down as possible in best_ref
8356 101053 JOIN_TAB **pos = best_ref + const_tables + 1;
8357
2/2
✓ Branch 0 taken 699 times.
✓ Branch 1 taken 101053 times.
101752 for (JOIN_TAB *next = best_ref[const_tables]; next != tab; pos++) {
8358 699 JOIN_TAB *const tmp = pos[0];
8359 699 pos[0] = next;
8360 699 next = tmp;
8361 }
8362 101053 best_ref[const_tables] = tab;
8363
8364
2/2
✓ Branch 0 taken 85410 times.
✓ Branch 1 taken 15643 times.
101053 tab->set_type(key ? JT_CONST : JT_SYSTEM);
8365
8366 101055 const_table_map |= tab->table_ref->map();
8367
8368 101055 const_tables++;
8369 101055 }
8370
8371 150663 void JOIN::make_outerjoin_info() {
8372
1/2
✓ Branch 0 taken 150679 times.
✗ Branch 1 not taken.
150663 DBUG_TRACE;
8373
8374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 150679 times.
150679 assert(query_block->outer_join);
8375
4/6
✓ Branch 0 taken 150671 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 150671 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 150672 times.
✗ Branch 5 not taken.
150679 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
8376
8377
1/2
✓ Branch 0 taken 150680 times.
✗ Branch 1 not taken.
150680 query_block->reset_nj_counters();
8378
8379
2/2
✓ Branch 0 taken 1238879 times.
✓ Branch 1 taken 150703 times.
1389582 for (uint i = const_tables; i < tables; ++i) {
8380 1238879 JOIN_TAB *const tab = best_ref[i];
8381 1238879 TABLE *const table = tab->table();
8382
2/2
✓ Branch 0 taken 270366 times.
✓ Branch 1 taken 968539 times.
1238905 if (!table) continue;
8383
8384 968539 TABLE_LIST *const tbl = tab->table_ref;
8385 /*
8386 If 'tbl' is inside a SJ/AJ nest served by materialization, we must
8387 limit setting first_inner, last_inner and first_upper for join nests
8388 inside the materialized table. Indeed it is the SJ-tmp table, and not
8389 'tbl', which interacts with the nests outer to the SJ/AJ nest.
8390 */
8391 const bool sj_mat_inner =
8392
1/2
✓ Branch 0 taken 968548 times.
✗ Branch 1 not taken.
968539 sj_is_materialize_strategy(tab->get_sj_strategy());
8393
8394
2/2
✓ Branch 0 taken 401749 times.
✓ Branch 1 taken 566800 times.
968549 if (tbl->outer_join) {
8395 /*
8396 Table tab is the only one inner table for outer join.
8397 (Like table t4 for the table reference t3 LEFT JOIN t4 ON t3.a=t4.a
8398 is in the query above.)
8399 */
8400 401749 tab->set_last_inner(i);
8401 401750 tab->set_first_inner(i);
8402
1/2
✓ Branch 0 taken 401749 times.
✗ Branch 1 not taken.
401748 tab->init_join_cond_ref(tbl);
8403 401749 tab->cond_equal = tbl->cond_equal;
8404 /*
8405 If this outer join nest is embedded in another join nest,
8406 link the join-tabs:
8407 */
8408 401749 TABLE_LIST *const outer_join_nest = tbl->outer_join_nest();
8409
2/2
✓ Branch 0 taken 425 times.
✓ Branch 1 taken 401322 times.
401747 if (outer_join_nest) {
8410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 425 times.
425 assert(outer_join_nest->nested_join->first_nested != NO_PLAN_IDX);
8411
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 425 times.
✓ Branch 2 taken 425 times.
✗ Branch 3 not taken.
425 if (!sj_mat_inner ||
8412 (tab->emb_sj_nest->sj_inner_tables &
8413 best_ref[outer_join_nest->nested_join->first_nested]
8414 ->table_ref->map()))
8415 425 tab->set_first_upper(outer_join_nest->nested_join->first_nested);
8416 }
8417 }
8418
2/2
✓ Branch 0 taken 12503 times.
✓ Branch 1 taken 964818 times.
977321 for (TABLE_LIST *embedding = tbl->embedding; embedding;
8419 8785 embedding = embedding->embedding) {
8420 // When reaching the outer tables of the materialized temporary table,
8421 // the decoration for this table is complete.
8422
4/4
✓ Branch 0 taken 1686 times.
✓ Branch 1 taken 10817 times.
✓ Branch 2 taken 1684 times.
✓ Branch 3 taken 2 times.
12503 if (sj_mat_inner && embedding == tab->emb_sj_nest) break;
8423 // Ignore join nests that are not outer join nests:
8424
2/2
✓ Branch 0 taken 6935 times.
✓ Branch 1 taken 3884 times.
10819 if (!embedding->join_cond_optim()) continue;
8425 3884 NESTED_JOIN *const nested_join = embedding->nested_join;
8426
2/2
✓ Branch 0 taken 1850 times.
✓ Branch 1 taken 2034 times.
3884 if (!nested_join->nj_counter) {
8427 /*
8428 Table tab is the first inner table for nested_join.
8429 Save reference to it in the nested join structure.
8430 */
8431 1850 nested_join->first_nested = i;
8432 // The table's condition is set to point to the join nest's condition
8433
1/2
✓ Branch 0 taken 1850 times.
✗ Branch 1 not taken.
1850 tab->init_join_cond_ref(embedding);
8434 1850 tab->cond_equal = tbl->cond_equal;
8435
8436 1850 TABLE_LIST *const outer_join_nest = embedding->outer_join_nest();
8437
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 1718 times.
1850 if (outer_join_nest) {
8438
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 132 times.
132 assert(outer_join_nest->nested_join->first_nested != NO_PLAN_IDX);
8439
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 132 times.
✓ Branch 2 taken 132 times.
✗ Branch 3 not taken.
132 if (!sj_mat_inner ||
8440 (tab->emb_sj_nest->sj_inner_tables &
8441 best_ref[outer_join_nest->nested_join->first_nested]
8442 ->table_ref->map()))
8443 132 tab->set_first_upper(outer_join_nest->nested_join->first_nested);
8444 }
8445 }
8446
2/2
✓ Branch 0 taken 3327 times.
✓ Branch 1 taken 557 times.
3884 if (tab->first_inner() == NO_PLAN_IDX)
8447 3327 tab->set_first_inner(nested_join->first_nested);
8448 /*
8449 If including the sj-mat tmp table, this also implicitly
8450 includes the inner tables of the sj-nest.
8451 */
8452 3884 nested_join->nj_counter +=
8453
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 3856 times.
3884 tab->sj_mat_exec() ? tab->sj_mat_exec()->table_count : 1;
8454
2/2
✓ Branch 0 taken 2034 times.
✓ Branch 1 taken 1850 times.
3884 if (nested_join->nj_counter < nested_join->nj_total) break;
8455 // Table tab is the last inner table for nested join.
8456 1850 best_ref[nested_join->first_nested]->set_last_inner(i);
8457 }
8458 }
8459 150703 }
8460
8461 /**
8462 Build a condition guarded by match variables for embedded outer joins.
8463 When generating a condition for a table as part of an outer join condition
8464 or the WHERE condition, the table in question may also be part of an
8465 embedded outer join. In such cases, the condition must be guarded by
8466 the match variable for this embedded outer join. Such embedded outer joins
8467 may also be recursively embedded in other joins.
8468
8469 The function recursively adds guards for a condition ascending from tab
8470 to root_tab, which is the first inner table of an outer join,
8471 or NULL if the condition being handled is the WHERE clause.
8472
8473 @param join the current join
8474 @param idx index of the first inner table for the inner-most outer join
8475 @param cond the predicate to be guarded (must be set)
8476 @param root_idx index of the inner table to stop at
8477 (is NO_PLAN_IDX if this is the WHERE clause)
8478
8479 @return
8480 - pointer to the guarded predicate, if success
8481 - NULL if error
8482 */
8483
8484 2762483 static Item *add_found_match_trig_cond(JOIN *join, plan_idx idx, Item *cond,
8485 plan_idx root_idx) {
8486
4/6
✓ Branch 0 taken 2762486 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2762487 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2762483 times.
✓ Branch 5 taken 4 times.
2762483 ASSERT_BEST_REF_IN_JOIN_ORDER(join);
8487
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2762485 times.
2762480 assert(cond->is_bool_func());
8488
8489
2/2
✓ Branch 0 taken 3902 times.
✓ Branch 1 taken 2762473 times.
2766387 for (; idx != root_idx; idx = join->best_ref[idx]->first_upper()) {
8490
2/4
✓ Branch 0 taken 3902 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3902 times.
7804 if (!(cond = new Item_func_trig_cond(cond, nullptr, join, idx,
8491
1/2
✓ Branch 0 taken 3902 times.
✗ Branch 1 not taken.
7804 Item_func_trig_cond::FOUND_MATCH)))
8492 return nullptr;
8493
8494 3902 cond->quick_fix_field();
8495 3902 cond->update_used_tables();
8496 }
8497
8498 2762473 return cond;
8499 }
8500
8501 /**
8502 Helper for JOIN::attach_join_conditions().
8503 Attaches bits of 'join_cond' to each table in the range [first_inner,
8504 last_tab], with proper guards.
8505 If 'sj_mat_cond' is true, we do not see first_inner (and tables on the same
8506 level of it) as inner to anything, as they're at the top from the POV of
8507 the materialization of the tmp table. So, if the SJ-mat nest is A LJ B,
8508 A will get a part of condition without any guard; B will get another part
8509 with a guard on A->found_match. It's like pushing a WHERE.
8510 */
8511 403560 bool JOIN::attach_join_condition_to_nest(plan_idx first_inner,
8512 plan_idx last_tab, Item *join_cond,
8513 bool is_sj_mat_cond) {
8514 /*
8515 Add the constant part of the join condition to the first inner table
8516 of the outer join.
8517 */
8518 Item *cond =
8519 403560 make_cond_for_table(thd, join_cond, const_table_map, table_map(0), false);
8520
2/2
✓ Branch 0 taken 365 times.
✓ Branch 1 taken 403194 times.
403559 if (cond) {
8521
2/2
✓ Branch 0 taken 355 times.
✓ Branch 1 taken 10 times.
365 if (!is_sj_mat_cond) {
8522
1/2
✓ Branch 0 taken 355 times.
✗ Branch 1 not taken.
710 cond = new Item_func_trig_cond(cond, nullptr, this, first_inner,
8523
1/2
✓ Branch 0 taken 355 times.
✗ Branch 1 not taken.
710 Item_func_trig_cond::IS_NOT_NULL_COMPL);
8524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 355 times.
355 if (!cond) return true;
8525
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 355 times.
355 if (cond->fix_fields(thd, nullptr)) return true;
8526 }
8527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 355 times.
365 if (best_ref[first_inner]->and_with_condition(cond)) return true;
8528 }
8529 /*
8530 Split the non-constant part of the join condition into parts that
8531 can be attached to the inner tables of the outer join.
8532 */
8533
2/2
✓ Branch 0 taken 405700 times.
✓ Branch 1 taken 403560 times.
809260 for (plan_idx i = first_inner; i <= last_tab; ++i) {
8534 405700 table_map prefix_tables = best_ref[i]->prefix_tables();
8535 405711 table_map added_tables = best_ref[i]->added_tables();
8536
8537 /*
8538 When handling the first inner table of an outer join, we may also
8539 reference all tables ahead of this table:
8540 */
8541
2/2
✓ Branch 0 taken 403560 times.
✓ Branch 1 taken 2156 times.
405716 if (i == first_inner) added_tables = prefix_tables;
8542 /*
8543 We need RAND_TABLE_BIT on the last inner table, in case there is a
8544 non-deterministic function in the join condition.
8545 (RAND_TABLE_BIT is set for the last table of the join plan,
8546 but this is not sufficient for join conditions, which may have a
8547 last inner table that is ahead of the last table of the join plan).
8548 */
8549
2/2
✓ Branch 0 taken 403559 times.
✓ Branch 1 taken 2157 times.
405716 if (i == last_tab) {
8550 403559 prefix_tables |= RAND_TABLE_BIT;
8551 403559 added_tables |= RAND_TABLE_BIT;
8552 }
8553 cond =
8554 405716 make_cond_for_table(thd, join_cond, prefix_tables, added_tables, false);
8555
2/2
✓ Branch 0 taken 1373 times.
✓ Branch 1 taken 404339 times.
405712 if (cond == nullptr) continue;
8556 /*
8557 If the table is part of an outer join that is embedded in the
8558 outer join currently being processed, wrap the condition in
8559 triggered conditions for match variables of such embedded outer joins.
8560 */
8561
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 404330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 404342 times.
808679 if (!(cond = add_found_match_trig_cond(
8562 404339 this, best_ref[i]->first_inner(), cond,
8563 is_sj_mat_cond ? NO_PLAN_IDX : first_inner)))
8564 return true;
8565
8566
2/2
✓ Branch 0 taken 404333 times.
✓ Branch 1 taken 9 times.
404342 if (!is_sj_mat_cond) {
8567 // Add the guard turning the predicate off for the null-complemented row.
8568
1/2
✓ Branch 0 taken 404328 times.
✗ Branch 1 not taken.
808660 cond = new Item_func_trig_cond(cond, nullptr, this, first_inner,
8569
1/2
✓ Branch 0 taken 404332 times.
✗ Branch 1 not taken.
808661 Item_func_trig_cond::IS_NOT_NULL_COMPL);
8570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 404332 times.
404332 if (!cond) return true;
8571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 404335 times.
404332 if (cond->fix_fields(thd, nullptr)) return true;
8572 }
8573 // Add the generated condition to the existing table condition
8574
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 404338 times.
404344 if (best_ref[i]->and_with_condition(cond)) return true;
8575 }
8576 403560 return false;
8577 }
8578
8579 /**
8580 Attach outer join conditions to generated table conditions in an optimal way.
8581
8582 @param last_tab - Last table that has been added to the current plan.
8583 Pre-condition: If this is the last inner table of an outer
8584 join operation, a join condition is attached to the first
8585 inner table of that outer join operation.
8586
8587 @return false if success, true if error.
8588
8589 Outer join conditions are attached to individual tables, but we can analyze
8590 those conditions only when reaching the last inner table of an outer join
8591 operation. Notice also that a table can be last within several outer join
8592 nests, hence the outer for() loop of this function.
8593
8594 Example:
8595 SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.a=t2.a
8596
8597 Table t3 is last both in the join nest (t2 - t3) and in (t1 - (t2 - t3))
8598 Thus, join conditions for both join nests will be evaluated when reaching
8599 this table.
8600
8601 For each outer join operation processed, the join condition is split
8602 optimally over the inner tables of the outer join. The split-out conditions
8603 are later referred to as table conditions (but note that several table
8604 conditions stemming from different join operations may be combined into
8605 a composite table condition).
8606
8607 Example:
8608 Consider the above query once more.
8609 The predicate t1.a=t2.a can be evaluated when rows from t1 and t2 are ready,
8610 ie at table t2. The predicate t2.a=t3.a can be evaluated at table t3.
8611
8612 Each non-constant split-out table condition is guarded by a match variable
8613 that enables it only when a matching row is found for all the embedded
8614 outer join operations.
8615
8616 Each split-out table condition is guarded by a variable that turns the
8617 condition off just before a null-complemented row for the outer join
8618 operation is formed. Thus, the join condition will not be checked for
8619 the null-complemented row.
8620 */
8621
8622 3826452 bool JOIN::attach_join_conditions(plan_idx last_tab) {
8623
1/2
✓ Branch 0 taken 3826471 times.
✗ Branch 1 not taken.
3826452 DBUG_TRACE;
8624
4/6
✓ Branch 0 taken 3826472 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3826456 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 3826468 times.
✗ Branch 5 not taken.
3826471 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
8625
8626 3826467 JOIN_TAB *lt = best_ref[last_tab];
8627
8628 3826467 for (plan_idx first_inner = lt->first_inner();
8629
6/6
✓ Branch 0 taken 405530 times.
✓ Branch 1 taken 3824480 times.
✓ Branch 2 taken 403550 times.
✓ Branch 3 taken 1980 times.
✓ Branch 4 taken 403550 times.
✓ Branch 5 taken 3826460 times.
4635540 first_inner != NO_PLAN_IDX &&
8630 405530 best_ref[first_inner]->last_inner() == last_tab;
8631 403544 first_inner = best_ref[first_inner]->first_upper()) {
8632 /*
8633 Table last_tab is the last inner table of an outer join, locate
8634 the corresponding join condition from the first inner table of the
8635 same outer join:
8636 */
8637 403550 Item *const join_cond = best_ref[first_inner]->join_cond();
8638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 403549 times.
403549 assert(join_cond);
8639
2/4
✓ Branch 0 taken 403544 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 403544 times.
403549 if (attach_join_condition_to_nest(first_inner, last_tab, join_cond, false))
8640 return true;
8641 }
8642
3/4
✓ Branch 0 taken 3826469 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2374 times.
✓ Branch 3 taken 3824096 times.
3826460 if (sj_is_materialize_strategy(lt->get_sj_strategy())) {
8643 2374 plan_idx mat_tbl = NO_PLAN_IDX;
8644 /*
8645 The SJ nest's condition contains both the SJ equality condition and the
8646 WHERE of the replaced subquery. This WHERE must be pushed to SJ-inner
8647 tables for evaluation during materialization!
8648 */
8649 2374 Semijoin_mat_exec *sjm = nullptr;
8650 2374 for (plan_idx j = last_tab;; j--) {
8651 17812 sjm = best_ref[j]->sj_mat_exec();
8652
4/4
✓ Branch 0 taken 2384 times.
✓ Branch 1 taken 15428 times.
✓ Branch 2 taken 2374 times.
✓ Branch 3 taken 10 times.
17812 if (sjm && sjm->sj_nest == lt->emb_sj_nest) {
8653 // 'j' is the sj-mat tmp table
8654 2374 mat_tbl = j;
8655 2374 break;
8656 }
8657 }
8658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2374 times.
2374 assert(sjm);
8659
2/2
✓ Branch 0 taken 934 times.
✓ Branch 1 taken 1440 times.
2374 if (sjm->inner_table_index + sjm->table_count - 1 == (uint)last_tab) {
8660 // we're at last table of sjmat nest
8661 934 auto join_cond = best_ref[mat_tbl]->join_cond();
8662
5/8
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 924 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 934 times.
934 if (join_cond && attach_join_condition_to_nest(sjm->inner_table_index,
8663 last_tab, join_cond, true))
8664 return true;
8665 }
8666 }
8667
8668 /*
8669 See if 'last_tab' is the first inner of an antijoin nest,
8670 then add a IS NULL condition on it.
8671 By attaching the condition to the first inner table, we know that if
8672 it is not satisfied we can just jump back to the table right before
8673 it.
8674 */
8675
4/4
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 13592 times.
✓ Branch 2 taken 197 times.
✓ Branch 3 taken 27 times.
14040 if (lt->table_ref->embedding && lt->table_ref->embedding->is_aj_nest() &&
8676
5/6
✓ Branch 0 taken 13816 times.
✓ Branch 1 taken 3812654 times.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
✓ Branch 5 taken 3826272 times.
3840500 last_tab == lt->first_inner() &&
8677 /*
8678 Exception: in A AJ (B LJ C) where C is a single table: there is no
8679 join nest for C as it's single; C->embedding is thus the AJ nest; but
8680 C->first_inner() is C (as it's the first inner of the LJ operation).
8681 In that case it's not the first inner table of the AJ.
8682 Catch this case:
8683 */
8684 198 !lt->table_ref->join_cond()) {
8685
1/2
✓ Branch 0 taken 188 times.
✗ Branch 1 not taken.
376 Item *cond = new Item_func_false();
8686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 188 times.
188 if (!cond) return true;
8687 // This is a signal for JOIN::create_access_paths
8688 188 cond->item_name.set(antijoin_null_cond);
8689 /*
8690 For A AJ B ON COND, we need an IS NULL condition which
8691 is tested on the result rows of A LEFT JOIN B ON COND.
8692 It must be tested only after the "match status" of a row of B has been
8693 decided, so is wrapped in a condition triggered by B->found_match.
8694 To have it test IS NULL, it's wrapped in a triggered condition which is
8695 false if B is not NULL-complemented.
8696 We needn't wrap this condition with triggers from upper nests, hence the
8697 last argument of the call below.
8698 */
8699
1/2
✓ Branch 0 taken 188 times.
✗ Branch 1 not taken.
188 cond = add_found_match_trig_cond(this, last_tab, cond, lt->first_upper());
8700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 188 times.
188 if (!cond) return true;
8701
1/2
✓ Branch 0 taken 188 times.
✗ Branch 1 not taken.
376 cond = new Item_func_trig_cond(cond, nullptr, this, last_tab,
8702
1/2
✓ Branch 0 taken 188 times.
✗ Branch 1 not taken.
376 Item_func_trig_cond::IS_NOT_NULL_COMPL);
8703
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 188 times.
188 if (!cond) return true;
8704
2/4
✓ Branch 0 taken 188 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 188 times.
188 if (cond->fix_fields(thd, nullptr)) return true;
8705
2/4
✓ Branch 0 taken 188 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 188 times.
188 if (lt->and_with_condition(cond)) return true;
8706 188 lt->table()->reginfo.not_exists_optimize = true;
8707
8708 // The relevant secondary engines don't support antijoin, so don't enable
8709 // this optimization for them.
8710
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 177 times.
188 assert(thd->secondary_engine_optimization() !=
8711 Secondary_engine_optimization::SECONDARY);
8712 }
8713
8714 3826449 return false;
8715 3826449 }
8716
8717 /*****************************************************************************
8718 Remove calculation with tables that aren't yet read. Remove also tests
8719 against fields that are read through key where the table is not a
8720 outer join table.
8721 We can't remove tests that are made against columns which are stored
8722 in sorted order.
8723 *****************************************************************************/
8724
8725 3420475 static Item *part_of_refkey(TABLE *table, TABLE_REF *ref, const Field *field) {
8726 3420475 uint ref_parts = ref->key_parts;
8727
2/2
✓ Branch 0 taken 2750610 times.
✓ Branch 1 taken 669865 times.
3420475 if (ref_parts) {
8728
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 2750533 times.
2750610 if (ref->has_guarded_conds()) return nullptr;
8729
8730 2750533 const KEY_PART_INFO *key_part = table->key_info[ref->key].key_part;
8731
8732
2/2
✓ Branch 0 taken 3511008 times.
✓ Branch 1 taken 117731 times.
3628739 for (uint part = 0; part < ref_parts; part++, key_part++)
8733
4/4
✓ Branch 0 taken 2643640 times.
✓ Branch 1 taken 867373 times.
✓ Branch 2 taken 2632807 times.
✓ Branch 3 taken 878206 times.
6154648 if (field->eq(key_part->field) &&
8734
2/2
✓ Branch 0 taken 2632806 times.
✓ Branch 1 taken 10834 times.
2643640 !(key_part->key_part_flag & HA_PART_KEY_SEG))
8735 2632807 return ref->items[part];
8736 }
8737 787596 return nullptr;
8738 }
8739
8740 2503057 bool ref_lookup_subsumes_comparison(Field *field, Item *right_item) {
8741 2503057 right_item = right_item->real_item();
8742
2/2
✓ Branch 0 taken 1802831 times.
✓ Branch 1 taken 700246 times.
2503074 if (right_item->type() == Item::FIELD_ITEM)
8743 1802831 return (field->eq_def(down_cast<Item_field *>(right_item)->field));
8744 /* remove equalities injected by IN->EXISTS transformation */
8745
2/2
✓ Branch 0 taken 149 times.
✓ Branch 1 taken 700095 times.
700246 else if (right_item->type() == Item::CACHE_ITEM)
8746 149 return down_cast<Item_cache *>(right_item)->eq_def(field);
8747
6/6
✓ Branch 0 taken 700027 times.
✓ Branch 1 taken 66 times.
✓ Branch 2 taken 700008 times.
✓ Branch 3 taken 21 times.
✓ Branch 4 taken 700012 times.
✓ Branch 5 taken 83 times.
700095 if (right_item->const_for_execution() && !right_item->is_null()) {
8748 /*
8749 We can remove all fields except:
8750 1. String data types:
8751 - For BINARY/VARBINARY fields with equality against a
8752 string: Ref access can return more rows than match the
8753 string. The reason seems to be that the string constant
8754 is not "padded" to the full length of the field when
8755 setting up ref access. @todo Change how ref access for
8756 BINARY/VARBINARY fields are done so that only qualifying
8757 rows are returned from the storage engine.
8758 2. Float data type: Comparison of float can differ
8759 - When we search "WHERE field=value" using an index,
8760 the "value" side is converted from double to float by
8761 Field_float::store(), then two floats are compared.
8762 - When we search "WHERE field=value" without indexes,
8763 the "field" side is converted from float to double by
8764 Field_float::val_real(), then two doubles are compared.
8765 */
8766
4/4
✓ Branch 0 taken 29246 times.
✓ Branch 1 taken 670760 times.
✓ Branch 2 taken 731 times.
✓ Branch 3 taken 699274 times.
729257 if (field->type() == MYSQL_TYPE_STRING &&
8767
2/2
✓ Branch 0 taken 731 times.
✓ Branch 1 taken 28514 times.
29246 field->charset()->pad_attribute == NO_PAD) {
8768 /*
8769 For "NO PAD" collations on CHAR columns, this function must return
8770 false, because removal of trailing space in CHAR columns makes the
8771 table value and the index value compare differently. As the column
8772 strips trailing spaces, it can return false candidates. Further
8773 comparison of the actual table values is required.
8774 */
8775 731 return false;
8776 }
8777 699274 if (!((field->type() == MYSQL_TYPE_STRING || // 1
8778
2/2
✓ Branch 0 taken 414971 times.
✓ Branch 1 taken 255793 times.
670762 field->type() == MYSQL_TYPE_VARCHAR) &&
8779
6/6
✓ Branch 0 taken 670762 times.
✓ Branch 1 taken 28514 times.
✓ Branch 2 taken 443463 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 699266 times.
✓ Branch 5 taken 12 times.
1813513 field->binary()) &&
8780
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 699260 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 5 times.
699256 !(field->type() == MYSQL_TYPE_FLOAT && field->decimals() > 0)) // 2
8781 {
8782 699266 return !right_item->save_in_field_no_warnings(field, true);
8783 }
8784 }
8785 95 return false;
8786 }
8787
8788 /**
8789 @brief
8790 Identify redundant predicates.
8791
8792 @details
8793 Test if the equality predicate 'left_item = right_item' is redundant
8794 due to a REF-access already being set up on the table, where 'left_item' is
8795 part of the REF-key being used, and 'right_item' is equal to the key value
8796 specified for that field in the key.
8797 In such cases the predicate is known to be 'true' for any rows retrieved
8798 from that table. Thus it is redundant.
8799
8800 @param left_item The Item_field possibly being part of A ref-KEY.
8801 @param right_item The equality value specified for 'left_item'.
8802
8803 @return 'true' if the predicate is redundant.
8804
8805 @note See comments in reduce_cond_for_table() about careful
8806 usage/modifications of test_if_ref().
8807 */
8808
8809 3421459 static bool test_if_ref(Item_field *left_item, Item *right_item) {
8810
2/2
✓ Branch 0 taken 558 times.
✓ Branch 1 taken 3420901 times.
3421459 if (left_item->depended_from)
8811 558 return false; // don't even read join_tab of inner subquery!
8812 3420901 Field *field = left_item->field;
8813 3420901 JOIN_TAB *join_tab = field->table->reginfo.join_tab;
8814
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3420886 times.
3420901 if (join_tab == nullptr) return false;
8815
8816
3/6
✓ Branch 0 taken 3420914 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3420911 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3420912 times.
✗ Branch 5 not taken.
3420886 ASSERT_BEST_REF_IN_JOIN_ORDER(join_tab->join());
8817
8818 // No need to change const test
8819
6/6
✓ Branch 0 taken 3420678 times.
✓ Branch 1 taken 233 times.
✓ Branch 2 taken 3420474 times.
✓ Branch 3 taken 204 times.
✓ Branch 4 taken 3420475 times.
✓ Branch 5 taken 436 times.
6841589 if (!field->table->const_table &&
8820 /* "ref_or_null" implements "x=y or x is null", not "x=y" */
8821 3420678 (join_tab->type() != JT_REF_OR_NULL)) {
8822 3420475 Item *ref_item = part_of_refkey(field->table, &join_tab->ref(), field);
8823
4/4
✓ Branch 0 taken 2632807 times.
✓ Branch 1 taken 787668 times.
✓ Branch 2 taken 2502880 times.
✓ Branch 3 taken 129903 times.
5923382 return (ref_item && ref_item->eq(right_item, true) &&
8824
2/2
✓ Branch 0 taken 2495138 times.
✓ Branch 1 taken 7769 times.
5923358 ref_lookup_subsumes_comparison(field, right_item));
8825 }
8826 436 return false; // keep predicate
8827 }
8828
8829 /**
8830 @brief
8831 Remove redundant predicates from condition, return the reduced condition.
8832
8833 @details
8834 A predicate of the form 'field = value' may be redundant if the
8835 (ref-) access chosen for the table use an index containing 'field',
8836 where 'value' is specified as (part of) its ref-key. This method remove
8837 such redundant predicates, thus reducing the condition, possibly
8838 eliminating it entirely.
8839
8840 If comparing 'values' against outer-joined tables, these are possibly
8841 'null-extended'. Thus the usage of these values in the ref-key, is not
8842 sufficient anymore to guarantee that 'field = value' is 'TRUE'.
8843 The 'null_extended' argument hold the table_map of any such possibly
8844 null-extended tables which are excluded from the above 'reduce' logic.
8845
8846 Any tables referred in Item_func_trig_cond(FOUND_MATCH) conditions are
8847 aggregated into this null_extended table_map.
8848
8849 @param cond The condition to be 'reduced'.
8850 @param null_extended table_map of possibly null-extended outer-tables.
8851
8852 @return The condition with redundant predicates removed,
8853 possibly nullptr.
8854 */
8855 6817517 static Item *reduce_cond_for_table(Item *cond, table_map null_extended) {
8856
1/2
✓ Branch 0 taken 6817529 times.
✗ Branch 1 not taken.
6817517 DBUG_TRACE;
8857
5/8
✓ Branch 0 taken 6817529 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6817523 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
6817529 DBUG_EXECUTE("where",
8858 print_where(current_thd, cond, "cond term", QT_ORDINARY););
8859
8860
3/4
✓ Branch 0 taken 6817527 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1405331 times.
✓ Branch 3 taken 5412196 times.
6817529 if (cond->type() == Item::COND_ITEM) {
8861 1405331 List<Item> *arguments = down_cast<Item_cond *>(cond)->argument_list();
8862
1/2
✓ Branch 0 taken 1405333 times.
✗ Branch 1 not taken.
1405332 List_iterator<Item> li(*arguments);
8863
3/4
✓ Branch 0 taken 1405330 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1385199 times.
✓ Branch 3 taken 20131 times.
1405333 if (down_cast<Item_cond *>(cond)->functype() == Item_func::COND_AND_FUNC) {
8864 Item *item;
8865
2/2
✓ Branch 0 taken 3598668 times.
✓ Branch 1 taken 1385198 times.
4983869 while ((item = li++)) {
8866
1/2
✓ Branch 0 taken 3598676 times.
✗ Branch 1 not taken.
3598668 Item *upd_item = reduce_cond_for_table(item, null_extended);
8867
2/2
✓ Branch 0 taken 1418163 times.
✓ Branch 1 taken 2180513 times.
3598676 if (upd_item == nullptr) {
8868
1/2
✓ Branch 0 taken 1418157 times.
✗ Branch 1 not taken.
1418163 li.remove();
8869
2/2
✓ Branch 0 taken 2059 times.
✓ Branch 1 taken 2178454 times.
2180513 } else if (upd_item != item) {
8870 2059 li.replace(upd_item);
8871 }
8872 }
8873
3/3
✓ Branch 0 taken 291460 times.
✓ Branch 1 taken 274852 times.
✓ Branch 2 taken 818886 times.
1385198 switch (arguments->elements) {
8874 291460 case 0:
8875 566329 return nullptr; // All 'true' -> And-cond true
8876 274852 case 1:
8877 274852 return arguments->head();
8878 }
8879 } else { // Or list
8880 Item *item;
8881
2/2
✓ Branch 0 taken 50410 times.
✓ Branch 1 taken 20118 times.
70528 while ((item = li++)) {
8882
1/2
✓ Branch 0 taken 50414 times.
✗ Branch 1 not taken.
50410 Item *upd_item = reduce_cond_for_table(item, null_extended);
8883
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 50397 times.
50414 if (upd_item == nullptr) {
8884 17 return nullptr; // Term 'true' -> entire Or-cond true
8885
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 50337 times.
50397 } else if (upd_item != item) {
8886 60 li.replace(upd_item);
8887 }
8888 }
8889 }
8890
3/4
✓ Branch 0 taken 5412194 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5412177 times.
✓ Branch 3 taken 17 times.
5412196 } else if (cond->type() == Item::FUNC_ITEM) {
8891 5412177 Item_func *func = down_cast<Item_func *>(cond);
8892
3/4
✓ Branch 0 taken 5412159 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 409210 times.
✓ Branch 3 taken 5002949 times.
5412180 if (func->functype() == Item_func::TRIG_COND_FUNC) {
8893 409210 Item_func_trig_cond *func_trig = down_cast<Item_func_trig_cond *>(func);
8894
2/2
✓ Branch 0 taken 3902 times.
✓ Branch 1 taken 405304 times.
409211 if (func_trig->get_trig_type() == Item_func_trig_cond::FOUND_MATCH) {
8895 /*
8896 All inner-tables are possible null-extended when evaluating
8897 the 'FOUND_MATCH'. Thus, predicates embedded in this trig_cond,
8898 referring these tables, should not be eliminated.
8899 -> Add to null_extended map.
8900 */
8901
1/2
✓ Branch 0 taken 3902 times.
✗ Branch 1 not taken.
3902 null_extended |= func_trig->get_inner_tables();
8902 }
8903
8904
1/2
✓ Branch 0 taken 409222 times.
✗ Branch 1 not taken.
409206 Item *cond_arg = func->arguments()[0];
8905
1/2
✓ Branch 0 taken 409222 times.
✗ Branch 1 not taken.
409222 Item *upd_arg = reduce_cond_for_table(cond_arg, null_extended);
8906
2/2
✓ Branch 0 taken 392504 times.
✓ Branch 1 taken 16718 times.
409222 if (upd_arg == nullptr) {
8907 392504 return nullptr;
8908 }
8909
1/2
✓ Branch 0 taken 16718 times.
✗ Branch 1 not taken.
16718 func->arguments()[0] = upd_arg;
8910 }
8911
8912
3/4
✓ Branch 0 taken 5002952 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3269051 times.
✓ Branch 3 taken 1733901 times.
5002949 else if (func->functype() == Item_func::EQ_FUNC) {
8913 /*
8914 Remove equalities that are guaranteed to be true by use of 'ref' access
8915 method.
8916 Note that ref access implements "table1.field1 <=>
8917 table2.indexed_field2", i.e. if it passed a NULL field1, it will return
8918 NULL indexed_field2 if there are.
8919 Thus the equality "table1.field1 = table2.indexed_field2",
8920 is equivalent to "ref access AND table1.field1 IS NOT NULL"
8921 i.e. "ref access and proper setting/testing of ref->null_rejecting".
8922 Thus, we must be careful, that when we remove equalities below we also
8923 set ref->null_rejecting, and test it at execution; otherwise wrong NULL
8924 matches appear.
8925 So:
8926 - for the optimization phase, the code which is below, and the code in
8927 test_if_ref(), and in add_key_field(), must be kept in sync: if the
8928 applicability conditions in one place are relaxed, they should also be
8929 relaxed elsewhere.
8930 - for the execution phase, all possible execution methods must test
8931 ref->null_rejecting.
8932 */
8933
2/4
✓ Branch 0 taken 3269060 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3269058 times.
✗ Branch 3 not taken.
3269051 Item *left_item = func->arguments()[0]->real_item();
8934
2/4
✓ Branch 0 taken 3269059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3269062 times.
✗ Branch 3 not taken.
3269058 Item *right_item = func->arguments()[1]->real_item();
8935
1/2
✓ Branch 0 taken 3269059 times.
✗ Branch 1 not taken.
3269062 if ((left_item->type() == Item::FIELD_ITEM &&
8936
3/4
✓ Branch 0 taken 3257769 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3257350 times.
✓ Branch 3 taken 419 times.
3257769 !(left_item->used_tables() & null_extended) &&
8937
7/8
✓ Branch 0 taken 3257769 times.
✓ Branch 1 taken 11290 times.
✓ Branch 2 taken 3257356 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 762741 times.
✓ Branch 5 taken 2494615 times.
✓ Branch 6 taken 2495130 times.
✓ Branch 7 taken 773938 times.
7300862 test_if_ref(down_cast<Item_field *>(left_item), right_item)) ||
8938
3/4
✓ Branch 0 taken 774453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 165021 times.
✓ Branch 3 taken 609432 times.
774450 (right_item->type() == Item::FIELD_ITEM &&
8939
3/4
✓ Branch 0 taken 165021 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 164132 times.
✓ Branch 3 taken 889 times.
165021 !(right_item->used_tables() & null_extended) &&
8940
3/4
✓ Branch 0 taken 164132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 522 times.
✓ Branch 3 taken 163610 times.
164132 test_if_ref(down_cast<Item_field *>(right_item), left_item))) {
8941 2495130 return nullptr;
8942 }
8943 }
8944 }
8945 3363578 return cond;
8946 6817541 }
8947
8948 /**
8949 @brief
8950 Remove redundant predicates and cache constant expressions.
8951
8952 @details
8953 Do a final round on pushed down table conditions and HAVING
8954 clause. Optimize them for faster execution by removing
8955 predicates being obsolete due to the access path selected
8956 for the table. Constant expressions are also cached
8957 to avoid evaluating them for each row being compared.
8958
8959 @return False if success, True if error
8960
8961 @note This function is run after conditions have been pushed down to
8962 individual tables, so transformation is applied to JOIN_TAB::condition
8963 and not to the WHERE condition.
8964 */
8965 1813863 bool JOIN::finalize_table_conditions() {
8966 /*
8967 Unnecessary to reduce conditions for const tables as they are only
8968 evaluated once.
8969 */
8970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1813882 times.
1813863 assert(!plan_is_const());
8971
5/6
✓ Branch 0 taken 1813879 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1813882 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1813877 times.
✓ Branch 5 taken 5 times.
1813882 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
8972
8973 1813880 Opt_trace_context *const trace = &thd->opt_trace;
8974
1/2
✓ Branch 0 taken 1813883 times.
✗ Branch 1 not taken.
1813880 Opt_trace_object trace_wrapper(trace);
8975
1/2
✓ Branch 0 taken 1813885 times.
✗ Branch 1 not taken.
1813883 Opt_trace_array trace_tables(trace, "finalizing_table_conditions");
8976
8977
2/2
✓ Branch 0 taken 6292002 times.
✓ Branch 1 taken 1813905 times.
8105907 for (uint i = const_tables; i < tables; i++) {
8978 6292002 Item *condition = best_ref[i]->condition();
8979
2/2
✓ Branch 0 taken 3532794 times.
✓ Branch 1 taken 2759217 times.
6292011 if (condition == nullptr) continue;
8980
8981 /*
8982 Table predicates known to be true by the selected
8983 (ref-)access method may be removed from the condition
8984 */
8985
1/2
✓ Branch 0 taken 2759224 times.
✗ Branch 1 not taken.
2759217 Opt_trace_object trace_cond(trace);
8986
1/2
✓ Branch 0 taken 2759229 times.
✗ Branch 1 not taken.
2759224 trace_cond.add_utf8_table(best_ref[i]->table_ref);
8987
1/2
✓ Branch 0 taken 2759227 times.
✗ Branch 1 not taken.
2759229 trace_cond.add("original_table_condition", condition);
8988
8989 /*
8990 Calculate the set of possibly NULL extended tables when 'condition'
8991 is evaluated. As it is evaluated on a found row from table, that
8992 table is subtracted from the nullable tables. Note that a FOUND_MATCH
8993 trigger is a special case, handled in reduce_cond_for_table().
8994 */
8995 const table_map null_extended =
8996 2759227 query_block->outer_join & ~best_ref[i]->table_ref->map();
8997
1/2
✓ Branch 0 taken 2759231 times.
✗ Branch 1 not taken.
2759226 condition = reduce_cond_for_table(condition, null_extended);
8998
3/4
✓ Branch 0 taken 1390798 times.
✓ Branch 1 taken 1368433 times.
✓ Branch 2 taken 1390800 times.
✗ Branch 3 not taken.
2759231 if (condition != nullptr) condition->update_used_tables();
8999
9000 /*
9001 Cache constant expressions in table conditions.
9002 (Moved down from WHERE- and ON-clauses)
9003 */
9004
2/2
✓ Branch 0 taken 1390800 times.
✓ Branch 1 taken 1368433 times.
2759233 if (condition != nullptr) {
9005
1/2
✓ Branch 0 taken 1390794 times.
✗ Branch 1 not taken.
1390800 cache_const_expr_arg cache_arg;
9006 1390794 cache_const_expr_arg *analyzer_arg = &cache_arg;
9007
1/2
✓ Branch 0 taken 1390797 times.
✗ Branch 1 not taken.
1390794 condition = condition->compile(
9008 &Item::cache_const_expr_analyzer, (uchar **)&analyzer_arg,
9009 &Item::cache_const_expr_transformer, (uchar *)&cache_arg);
9010
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1390796 times.
1390797 if (condition == nullptr) return true;
9011 }
9012
9013
1/2
✓ Branch 0 taken 2759220 times.
✗ Branch 1 not taken.
2759229 trace_cond.add("final_table_condition ", condition);
9014 2759220 best_ref[i]->set_condition(condition);
9015
2/2
✓ Branch 0 taken 2759228 times.
✓ Branch 1 taken 1 times.
2759234 }
9016
9017 /* Cache constant expressions in HAVING-clauses. */
9018
2/2
✓ Branch 0 taken 3526 times.
✓ Branch 1 taken 1810379 times.
1813905 if (having_cond != nullptr) {
9019
1/2
✓ Branch 0 taken 3526 times.
✗ Branch 1 not taken.
3526 cache_const_expr_arg cache_arg;
9020 3526 cache_const_expr_arg *analyzer_arg = &cache_arg;
9021
1/2
✓ Branch 0 taken 3526 times.
✗ Branch 1 not taken.
3526 having_cond = having_cond->compile(
9022 &Item::cache_const_expr_analyzer, (uchar **)&analyzer_arg,
9023 &Item::cache_const_expr_transformer, (uchar *)&cache_arg);
9024
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3526 times.
3526 if (having_cond == nullptr) return true;
9025 }
9026 1813905 return false;
9027 1813906 }
9028
9029 /**
9030 @brief
9031 Add keys to derived tables'/views' result tables in a list
9032
9033 @details
9034 This function generates keys for all derived tables/views of the query_block
9035 to which this join corresponds to with help of the TABLE_LIST:generate_keys
9036 function.
9037
9038 @return false all keys were successfully added.
9039 @return true OOM error
9040 */
9041
9042 3010 bool JOIN::generate_derived_keys() {
9043
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3010 times.
3010 assert(query_block->materialized_derived_table_count);
9044
9045
2/2
✓ Branch 0 taken 5434 times.
✓ Branch 1 taken 3010 times.
8444 for (TABLE_LIST *table = query_block->leaf_tables; table;
9046 5434 table = table->next_leaf) {
9047 5434 table->derived_keys_ready = true;
9048 /* Process tables that aren't materialized yet. */
9049
5/6
✓ Branch 0 taken 3181 times.
✓ Branch 1 taken 2253 times.
✓ Branch 2 taken 1803 times.
✓ Branch 3 taken 1378 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5434 times.
7237 if (table->uses_materialization() && !table->table->is_created() &&
9050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1803 times.
1803 table->generate_keys())
9051 return true;
9052 }
9053 3010 return false;
9054 }
9055
9056 /**
9057 For each materialized derived table/view, informs every TABLE of the key it
9058 will (not) use, segregates used keys from unused keys in TABLE::key_info,
9059 and eliminates unused keys.
9060 */
9061
9062 145210 void JOIN::finalize_derived_keys() {
9063
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 145210 times.
145210 assert(query_block->materialized_derived_table_count);
9064
4/6
✓ Branch 0 taken 145210 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 145211 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 145210 times.
✓ Branch 5 taken 1 times.
145210 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
9065
9066 145210 bool adjust_key_count = false;
9067 145210 table_map processed_tables = 0;
9068
9069
2/2
✓ Branch 0 taken 294054 times.
✓ Branch 1 taken 145212 times.
439266 for (uint i = 0; i < tables; i++) {
9070 294054 JOIN_TAB *tab = best_ref[i];
9071 294054 TABLE *table = tab->table();
9072 294055 TABLE_LIST *table_ref = tab->table_ref;
9073 /*
9074 Save chosen key description if:
9075 1) it's a materialized derived table
9076 2) it's not yet instantiated
9077 3) some keys are defined for it
9078 */
9079
2/2
✓ Branch 0 taken 145565 times.
✓ Branch 1 taken 2549 times.
148114 if (table && table_ref->uses_materialization() && // (1)
9080
6/6
✓ Branch 0 taken 148114 times.
✓ Branch 1 taken 145941 times.
✓ Branch 2 taken 142713 times.
✓ Branch 3 taken 2853 times.
✓ Branch 4 taken 1542 times.
✓ Branch 5 taken 292514 times.
584882 !table->is_created() && // (2)
9081
2/2
✓ Branch 0 taken 1542 times.
✓ Branch 1 taken 141171 times.
142713 table->s->keys > 0) // (3)
9082 {
9083 /*
9084 If there are two local references to the same CTE, and they use
9085 the same key, the iteration for the second reference is unnecessary.
9086 */
9087
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1531 times.
2340 if (processed_tables & table_ref->map()) continue;
9088
9089 1531 adjust_key_count = true;
9090
9091
1/2
✓ Branch 0 taken 1531 times.
✗ Branch 1 not taken.
1531 Key_map used_keys;
9092
9093 // Mark all unique indexes as in use, since they have an effect
9094 // (deduplication) whether any expression refers to them or not.
9095 // In particular, they are used if we want to materialize a UNION DISTINCT
9096 // directly into the derived table.
9097
2/2
✓ Branch 0 taken 10815 times.
✓ Branch 1 taken 1531 times.
12346 for (uint key_idx = 0; key_idx < table->s->keys; ++key_idx) {
9098
2/2
✓ Branch 0 taken 261 times.
✓ Branch 1 taken 10554 times.
10815 if (table->key_info[key_idx].flags & HA_NOSAME) {
9099 261 used_keys.set_bit(key_idx);
9100 }
9101 }
9102
9103 // Same for the hash key used for manual deduplication, if any. (It always
9104 // has index 0 if it exists.)
9105
2/2
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 1350 times.
1531 if (table->hash_field) {
9106 181 used_keys.set_bit(0);
9107 }
9108
9109 1531 Key_use *const keyuse = tab->position()->key;
9110
6/6
✓ Branch 0 taken 798 times.
✓ Branch 1 taken 733 times.
✓ Branch 2 taken 385 times.
✓ Branch 3 taken 413 times.
✓ Branch 4 taken 385 times.
✓ Branch 5 taken 1146 times.
1531 if (keyuse == nullptr && used_keys.is_clear_all()) {
9111 // Nothing uses any keys.
9112 385 tab->keys().clear_all();
9113 385 tab->const_keys.clear_all();
9114 385 continue;
9115 }
9116
9117 1146 Derived_refs_iterator it(table_ref);
9118
3/4
✓ Branch 0 taken 15331 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14185 times.
✓ Branch 3 taken 1146 times.
15331 while (TABLE *t = it.get_next()) {
9119 /*
9120 Eliminate possible keys created by this JOIN and which it
9121 doesn't use.
9122 Collect all keys of this table which are used by any reference in
9123 this query block. Any other query block doesn't matter as:
9124 - either it was optimized before, so it's not using a key we may
9125 want to drop.
9126 - or it was optimized in this same window, so:
9127 * either we own the window, then any key we may want to
9128 drop is not visible to it.
9129 * or it owns the window, then we are using only existing
9130 keys.
9131 - or it will be optimized after, so it's not using any key yet.
9132
9133 used_keys is a mix of possible used keys and existing used keys.
9134 */
9135
2/2
✓ Branch 0 taken 1193 times.
✓ Branch 1 taken 12992 times.
14185 if (t->pos_in_table_list->query_block == query_block) {
9136 1193 JOIN_TAB *jtab = t->reginfo.join_tab;
9137 1193 Key_use *keyuse_1 = jtab->position()->key;
9138
2/2
✓ Branch 0 taken 754 times.
✓ Branch 1 taken 439 times.
1193 if (keyuse_1) used_keys.set_bit(keyuse_1->key);
9139 }
9140 14185 }
9141
9142
1/2
✓ Branch 0 taken 1146 times.
✗ Branch 1 not taken.
1146 uint new_idx = table->s->find_first_unused_tmp_key(
9143 used_keys); // Also updates table->s->first_unused_tmp_key.
9144
2/2
✓ Branch 0 taken 413 times.
✓ Branch 1 taken 733 times.
1146 if (keyuse == nullptr) {
9145 413 continue;
9146 }
9147
9148 733 const uint old_idx = keyuse->key;
9149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 733 times.
733 assert(old_idx != new_idx);
9150
9151
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 730 times.
733 if (old_idx > new_idx) {
9152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 assert(table->s->owner_of_possible_tmp_keys == query_block);
9153 3 it.rewind();
9154
3/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 3 times.
7 while (TABLE *t = it.get_next()) {
9155 /*
9156 Unlike the collection of used_keys, references from other query
9157 blocks must be considered here, as they need a key_info array
9158 consistent with the to-be-changed table->s->keys.
9159 */
9160
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 t->move_tmp_key(old_idx, it.is_first());
9161 4 }
9162 } else
9163 730 new_idx = old_idx; // Index stays at same slot
9164
9165 /*
9166 If the key was created by earlier-optimized query blocks, and is
9167 already used by nonlocal references, those don't need any further
9168 update: they are already setup to use it and we're not moving the
9169 key.
9170 If the key was created by this query block, nonlocal references cannot
9171 possibly be referencing it.
9172 In both cases, only local references need to update their Key_use.
9173 */
9174 733 it.rewind();
9175
3/4
✓ Branch 0 taken 14295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13562 times.
✓ Branch 3 taken 733 times.
14295 while (TABLE *t = it.get_next()) {
9176
2/2
✓ Branch 0 taken 12806 times.
✓ Branch 1 taken 756 times.
13562 if (t->pos_in_table_list->query_block != query_block) continue;
9177 756 JOIN_TAB *jtab = t->reginfo.join_tab;
9178 756 Key_use *keyuse_1 = jtab->position()->key;
9179
3/4
✓ Branch 0 taken 744 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 744 times.
✗ Branch 3 not taken.
756 if (keyuse_1 && keyuse_1->key == old_idx) {
9180 744 processed_tables |= t->pos_in_table_list->map();
9181 744 const bool key_is_const = jtab->const_keys.is_set(old_idx);
9182 // tab->keys() was never set, so must be set
9183 744 jtab->keys().clear_all();
9184 744 jtab->keys().set_bit(new_idx);
9185 744 jtab->const_keys.clear_all();
9186
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 715 times.
744 if (key_is_const) tab->const_keys.set_bit(new_idx);
9187 744 for (Key_use *kit = keyuse_1;
9188
4/4
✓ Branch 0 taken 1124 times.
✓ Branch 1 taken 441 times.
✓ Branch 2 taken 821 times.
✓ Branch 3 taken 303 times.
1565 kit->table_ref == jtab->table_ref && kit->key == old_idx; kit++)
9189 821 kit->key = new_idx;
9190 }
9191 13562 }
9192 }
9193 }
9194
9195
2/2
✓ Branch 0 taken 143780 times.
✓ Branch 1 taken 1432 times.
145212 if (!adjust_key_count) return;
9196
9197 // Finally we know how many keys remain in the table.
9198
2/2
✓ Branch 0 taken 4701 times.
✓ Branch 1 taken 1432 times.
6133 for (uint i = 0; i < tables; i++) {
9199 4701 JOIN_TAB *tab = best_ref[i];
9200 4701 TABLE *table = tab->table();
9201 4701 TABLE_LIST *table_ref = tab->table_ref;
9202
8/8
✓ Branch 0 taken 2989 times.
✓ Branch 1 taken 1712 times.
✓ Branch 2 taken 1586 times.
✓ Branch 3 taken 1403 times.
✓ Branch 4 taken 1561 times.
✓ Branch 5 taken 25 times.
✓ Branch 6 taken 1541 times.
✓ Branch 7 taken 3160 times.
6262 if (table && table_ref->uses_materialization() && !table->is_created() &&
9203
2/2
✓ Branch 0 taken 1541 times.
✓ Branch 1 taken 20 times.
1561 table->s->keys > 0) {
9204
2/2
✓ Branch 0 taken 355 times.
✓ Branch 1 taken 1186 times.
1541 if (table->s->owner_of_possible_tmp_keys != query_block) continue;
9205 /*
9206 Release lock. As a bonus, avoid double work when this loop
9207 later processes another local reference to the same table (similar to
9208 the processed_tables map in the first loop).
9209 */
9210 1186 table->s->owner_of_possible_tmp_keys = nullptr;
9211 1186 Derived_refs_iterator it(table_ref);
9212
4/6
✓ Branch 0 taken 22761 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21575 times.
✓ Branch 3 taken 1186 times.
✓ Branch 4 taken 21575 times.
✗ Branch 5 not taken.
22761 while (TABLE *t = it.get_next()) t->drop_unused_tmp_keys(it.is_first());
9213 }
9214 }
9215 }
9216
9217 /**
9218 @brief
9219 Extract a condition that can be checked after reading given table
9220
9221 @param thd Current session.
9222 @param cond Condition to analyze
9223 @param tables Tables for which "current field values" are available
9224 @param used_table Table(s) that we are extracting the condition for (may
9225 also include PSEUDO_TABLE_BITS, and may be zero)
9226 @param exclude_expensive_cond Do not push expensive conditions
9227
9228 @retval <>NULL Generated condition
9229 @retval = NULL Already checked, OR error
9230
9231 @details
9232 Extract the condition that can be checked after reading the table(s)
9233 specified in @c used_table, given that current-field values for tables
9234 specified in @c tables bitmap are available.
9235 If @c used_table is 0, extract conditions for all tables in @c tables.
9236
9237 This function can be used to extract conditions relevant for a table
9238 in a join order. Together with its caller, it will ensure that all
9239 conditions are attached to the first table in the join order where all
9240 necessary fields are available, and it will also ensure that a given
9241 condition is attached to only one table.
9242 To accomplish this, first initialize @c tables to the empty
9243 set. Then, loop over all tables in the join order, set @c used_table to
9244 the bit representing the current table, accumulate @c used_table into the
9245 @c tables set, and call this function. To ensure correct handling of
9246 const expressions and outer references, add the const table map and
9247 OUTER_REF_TABLE_BIT to @c used_table for the first table. To ensure
9248 that random expressions are evaluated for the final table, add
9249 RAND_TABLE_BIT to @c used_table for the final table.
9250
9251 The function assumes that constant, inexpensive parts of the condition
9252 have already been checked. Constant, expensive parts will be attached
9253 to the first table in the join order, provided that the above call
9254 sequence is followed.
9255
9256 The call order will ensure that conditions covering tables in @c tables
9257 minus those in @c used_table, have already been checked.
9258
9259 The function takes into account that some parts of the condition are
9260 guaranteed to be true by employed 'ref' access methods (the code that
9261 does this is located at the end, search down for "EQ_FUNC").
9262
9263 @note
9264 make_cond_for_info_schema() uses an algorithm similar to
9265 make_cond_for_table().
9266 */
9267
9268 27059002 Item *make_cond_for_table(THD *thd, Item *cond, table_map tables,
9269 table_map used_table, bool exclude_expensive_cond) {
9270 /*
9271 May encounter an Item_cache_int as "condition" here, so cannot
9272 assert that it satisfies is_bool_func().
9273 */
9274 /*
9275 Ignore this condition if
9276 1. We are extracting conditions for a specific table, and
9277 2. that table is not referenced by the condition, but not if
9278 3. this is a constant condition not checked at optimization time and
9279 this is the first table we are extracting conditions for.
9280 (Assuming that used_table == tables for the first table.)
9281 */
9282 48200803 if (used_table && // 1
9283
6/6
✓ Branch 0 taken 21141786 times.
✓ Branch 1 taken 5917216 times.
✓ Branch 2 taken 11638866 times.
✓ Branch 3 taken 9502913 times.
✓ Branch 4 taken 11638842 times.
✓ Branch 5 taken 15420182 times.
38697897 !(cond->used_tables() & used_table) && // 2
9284
4/4
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 11638787 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 56 times.
11638866 !(cond->is_expensive() && used_table == tables)) // 3
9285 11638842 return nullptr;
9286
9287
2/2
✓ Branch 0 taken 3496799 times.
✓ Branch 1 taken 11923385 times.
15420182 if (cond->type() == Item::COND_ITEM) {
9288
2/2
✓ Branch 0 taken 3456765 times.
✓ Branch 1 taken 40037 times.
3496799 if (((Item_cond *)cond)->functype() == Item_func::COND_AND_FUNC) {
9289 /* Create new top level AND item */
9290
2/4
✓ Branch 0 taken 3456764 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3456768 times.
✗ Branch 3 not taken.
3456765 Item_cond_and *new_cond = new Item_cond_and;
9291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3456768 times.
3456768 if (!new_cond) return nullptr;
9292
1/2
✓ Branch 0 taken 3456768 times.
✗ Branch 1 not taken.
3456768 List_iterator<Item> li(*((Item_cond *)cond)->argument_list());
9293 Item *item;
9294
2/2
✓ Branch 0 taken 21653542 times.
✓ Branch 1 taken 3456705 times.
25110289 while ((item = li++)) {
9295
1/2
✓ Branch 0 taken 21653526 times.
✗ Branch 1 not taken.
21653542 Item *fix = make_cond_for_table(thd, item, tables, used_table,
9296 exclude_expensive_cond);
9297
3/4
✓ Branch 0 taken 4132985 times.
✓ Branch 1 taken 17520541 times.
✓ Branch 2 taken 4132980 times.
✗ Branch 3 not taken.
21653526 if (fix) new_cond->argument_list()->push_back(fix);
9298 }
9299
3/3
✓ Branch 0 taken 1375727 times.
✓ Branch 1 taken 858921 times.
✓ Branch 2 taken 1222121 times.
3456705 switch (new_cond->argument_list()->elements) {
9300 1375727 case 0:
9301 1375727 return nullptr; // Always true
9302 858921 case 1:
9303 858921 return new_cond->argument_list()->head();
9304 1222121 default:
9305
2/4
✓ Branch 0 taken 1222108 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1222108 times.
1222121 if (new_cond->fix_fields(thd, nullptr)) return nullptr;
9306 1222108 return new_cond;
9307 }
9308 } else { // Or list
9309
2/4
✓ Branch 0 taken 40037 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40037 times.
✗ Branch 3 not taken.
40037 Item_cond_or *new_cond = new Item_cond_or;
9310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40037 times.
40037 if (!new_cond) return nullptr;
9311
1/2
✓ Branch 0 taken 40037 times.
✗ Branch 1 not taken.
40037 List_iterator<Item> li(*((Item_cond *)cond)->argument_list());
9312 Item *item;
9313
2/2
✓ Branch 0 taken 70548 times.
✓ Branch 1 taken 19816 times.
90364 while ((item = li++)) {
9314
1/2
✓ Branch 0 taken 70548 times.
✗ Branch 1 not taken.
70548 Item *fix = make_cond_for_table(thd, item, tables, table_map(0),
9315 exclude_expensive_cond);
9316
2/2
✓ Branch 0 taken 20221 times.
✓ Branch 1 taken 50327 times.
70548 if (!fix) return nullptr; // Always true
9317
1/2
✓ Branch 0 taken 50327 times.
✗ Branch 1 not taken.
50327 new_cond->argument_list()->push_back(fix);
9318 }
9319
2/4
✓ Branch 0 taken 19816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19816 times.
19816 if (new_cond->fix_fields(thd, nullptr)) return nullptr;
9320 19816 return new_cond;
9321 }
9322 }
9323
9324 /*
9325 Omit this condition if
9326 1. Some tables referred by the condition are not available, or
9327 2. We are extracting conditions for all tables, the condition is
9328 considered 'expensive', and we want to delay evaluation of such
9329 conditions to the execution phase.
9330 */
9331
6/6
✓ Branch 0 taken 4930677 times.
✓ Branch 1 taken 6992706 times.
✓ Branch 2 taken 143645 times.
✓ Branch 3 taken 4787032 times.
✓ Branch 4 taken 6992744 times.
✓ Branch 5 taken 4930639 times.
12067030 if ((cond->used_tables() & ~tables) || // 1
9332
4/4
✓ Branch 0 taken 90338 times.
✓ Branch 1 taken 53307 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 90300 times.
143645 (!used_table && exclude_expensive_cond && cond->is_expensive())) // 2
9333 6992744 return nullptr;
9334
9335 4930639 return cond;
9336 }
9337
9338 /**
9339 Separates the predicates in a join condition and pushes them to the
9340 join step where all involved tables are available in the join prefix.
9341 ON clauses from JOIN expressions are also pushed to the most appropriate step.
9342
9343 @param join Join object where predicates are pushed.
9344
9345 @param cond Pointer to condition which may contain an arbitrary number of
9346 predicates, combined using AND, OR and XOR items.
9347 If NULL, equivalent to a predicate that returns true for all
9348 row combinations.
9349
9350
9351 @retval true Found impossible WHERE clause, or out-of-memory
9352 @retval false Other
9353 */
9354
9355 1903440 static bool make_join_query_block(JOIN *join, Item *cond) {
9356
4/6
✓ Branch 0 taken 1302885 times.
✓ Branch 1 taken 600555 times.
✓ Branch 2 taken 1302895 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1302895 times.
1903440 assert(cond == nullptr || cond->is_bool_func());
9357 1903450 THD *thd = join->thd;
9358 1903450 Opt_trace_context *const trace = &thd->opt_trace;
9359
1/2
✓ Branch 0 taken 1903458 times.
✗ Branch 1 not taken.
1903450 DBUG_TRACE;
9360
4/6
✓ Branch 0 taken 1903458 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1903455 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1903455 times.
✗ Branch 5 not taken.
1903458 ASSERT_BEST_REF_IN_JOIN_ORDER(join);
9361
9362 // Add IS NOT NULL conditions to table conditions:
9363
2/4
✓ Branch 0 taken 1903457 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1903457 times.
1903455 if (add_not_null_conds(join)) return true;
9364
9365 /*
9366 Extract constant conditions that are part of the WHERE clause.
9367 Constant parts of join conditions from outer joins are attached to
9368 the appropriate table condition in JOIN::attach_join_conditions().
9369 */
9370
2/2
✓ Branch 0 taken 1302896 times.
✓ Branch 1 taken 600561 times.
1903457 if (cond) /* Because of GroupIndexSkipScanIterator */
9371 { /* there may be a select without a cond. */
9372
2/2
✓ Branch 0 taken 452398 times.
✓ Branch 1 taken 850498 times.
1302896 if (join->primary_tables > 1)
9373
1/2
✓ Branch 0 taken 452398 times.
✗ Branch 1 not taken.
452398 cond->update_used_tables(); // Table number may have changed
9374
4/4
✓ Branch 0 taken 83928 times.
✓ Branch 1 taken 1218968 times.
✓ Branch 2 taken 82963 times.
✓ Branch 3 taken 1219934 times.
1386825 if (join->plan_is_const() &&
9375 83928 join->query_block->master_query_expression() ==
9376
2/2
✓ Branch 0 taken 82963 times.
✓ Branch 1 taken 966 times.
83929 thd->lex->unit) // The outer-most query block
9377 82963 join->const_table_map |= RAND_TABLE_BIT;
9378 }
9379 /*
9380 Extract conditions that depend on constant tables.
9381 The const part of the query's WHERE clause can be checked immediately
9382 and if it is not satisfied then the join has empty result
9383 */
9384 1903458 Item *const_cond = nullptr;
9385
2/2
✓ Branch 0 taken 1302897 times.
✓ Branch 1 taken 600561 times.
1903458 if (cond)
9386
1/2
✓ Branch 0 taken 1302894 times.
✗ Branch 1 not taken.
1302897 const_cond = make_cond_for_table(thd, cond, join->const_table_map,
9387 table_map(0), true);
9388
9389 // Add conditions added by add_not_null_conds()
9390
2/2
✓ Branch 0 taken 92245 times.
✓ Branch 1 taken 1903455 times.
1995700 for (uint i = 0; i < join->const_tables; i++) {
9391
2/4
✓ Branch 0 taken 92245 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 92245 times.
92245 if (and_conditions(&const_cond, join->best_ref[i]->condition()))
9392 return true;
9393 }
9394
4/6
✓ Branch 0 taken 1903455 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 1903430 times.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
1903455 DBUG_EXECUTE("where",
9395 print_where(thd, const_cond, "constants", QT_ORDINARY););
9396
4/4
✓ Branch 0 taken 88151 times.
✓ Branch 1 taken 1815298 times.
✓ Branch 2 taken 88151 times.
✓ Branch 3 taken 1815298 times.
1991600 if (const_cond != nullptr &&
9397
2/4
✓ Branch 0 taken 88151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88151 times.
✗ Branch 3 not taken.
88151 evaluate_during_optimization(const_cond, join->query_block)) {
9398
1/2
✓ Branch 0 taken 88151 times.
✗ Branch 1 not taken.
88151 const bool const_cond_result = const_cond->val_int() != 0;
9399
3/4
✓ Branch 0 taken 88151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 88149 times.
91070 if (thd->is_error()) return true;
9400
9401
1/2
✓ Branch 0 taken 88149 times.
✗ Branch 1 not taken.
88149 Opt_trace_object trace_const_cond(trace);
9402 176298 trace_const_cond.add("condition_on_constant_tables", const_cond)
9403
2/4
✓ Branch 0 taken 88149 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88149 times.
✗ Branch 3 not taken.
88149 .add("condition_value", const_cond_result);
9404
2/2
✓ Branch 0 taken 85230 times.
✓ Branch 1 taken 2919 times.
88149 if (const_cond_result) {
9405 /*
9406 If all the tables referred by the condition are const tables and
9407 if the condition is not expensive, we can remove the where condition
9408 as it will always evaluate to "true".
9409 */
9410 85230 if (join->plan_is_const() &&
9411
7/8
✓ Branch 0 taken 81007 times.
✓ Branch 1 taken 4223 times.
✓ Branch 2 taken 81007 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 81004 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 81003 times.
✓ Branch 7 taken 4227 times.
166234 !(cond->used_tables() & ~join->const_table_map) &&
9412
3/4
✓ Branch 0 taken 81004 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81003 times.
✓ Branch 3 taken 1 times.
81004 !cond->is_expensive()) {
9413
3/8
✓ Branch 0 taken 81003 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81003 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 81003 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
81003 DBUG_PRINT("info", ("Found always true WHERE condition"));
9414 81003 join->where_cond = nullptr;
9415 }
9416 } else {
9417
3/8
✓ Branch 0 taken 2919 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2919 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2919 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2919 DBUG_PRINT("info", ("Found impossible WHERE condition"));
9418 2919 return true;
9419 }
9420
2/2
✓ Branch 0 taken 85230 times.
✓ Branch 1 taken 2919 times.
88149 }
9421
9422 /*
9423 Extract remaining conditions from WHERE clause and join conditions,
9424 and attach them to the most appropriate table condition. This means that
9425 a condition will be evaluated as soon as all fields it depends on are
9426 available. For outer join conditions, the additional criterion is that
9427 we must have determined whether outer-joined rows are available, or
9428 have been NULL-extended, see JOIN::attach_join_conditions() for details.
9429 */
9430 {
9431
1/2
✓ Branch 0 taken 1900524 times.
✗ Branch 1 not taken.
1900528 Opt_trace_object trace_wrapper(trace);
9432
1/2
✓ Branch 0 taken 1900538 times.
✗ Branch 1 not taken.
1900524 Opt_trace_object trace_conditions(trace, "attaching_conditions_to_tables");
9433
1/2
✓ Branch 0 taken 1900532 times.
✗ Branch 1 not taken.
1900538 trace_conditions.add("original_condition", cond);
9434 Opt_trace_array trace_attached_comp(trace,
9435
1/2
✓ Branch 0 taken 1900536 times.
✗ Branch 1 not taken.
1900532 "attached_conditions_computation");
9436
9437
2/2
✓ Branch 0 taken 6381699 times.
✓ Branch 1 taken 1900549 times.
8282248 for (uint i = join->const_tables; i < join->tables; i++) {
9438 6381699 JOIN_TAB *const tab = join->best_ref[i];
9439
9440
2/2
✓ Branch 0 taken 2555257 times.
✓ Branch 1 taken 3826462 times.
6381699 if (!tab->position()) continue;
9441 /*
9442 first_inner is the X in queries like:
9443 SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
9444 */
9445 3826462 const plan_idx first_inner = tab->first_inner();
9446 3826468 const table_map used_tables = tab->prefix_tables();
9447 3826471 const table_map current_map = tab->added_tables();
9448 3826474 Item *tmp = nullptr;
9449
9450
2/2
✓ Branch 0 taken 3218317 times.
✓ Branch 1 taken 608157 times.
3826474 if (cond)
9451
1/2
✓ Branch 0 taken 3218312 times.
✗ Branch 1 not taken.
3218317 tmp = make_cond_for_table(thd, cond, used_tables, current_map, false);
9452 /* Add conditions added by add_not_null_conds(). */
9453
2/4
✓ Branch 0 taken 3826452 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3826452 times.
3826469 if (and_conditions(&tmp, tab->condition())) return true;
9454
9455
8/8
✓ Branch 0 taken 3218302 times.
✓ Branch 1 taken 608150 times.
✓ Branch 2 taken 860343 times.
✓ Branch 3 taken 2357959 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 860350 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 3826459 times.
3826452 if (cond && !tmp && tab->range_scan()) { // Outer join
9456
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 assert(tab->type() == JT_RANGE || tab->type() == JT_INDEX_MERGE);
9457 /*
9458 Hack to handle the case where we only refer to a table
9459 in the ON part of an OUTER JOIN. In this case we want the code
9460 below to check if we should use 'quick' instead.
9461 */
9462
3/8
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2 DBUG_PRINT("info", ("Item_func_true"));
9463
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 tmp = new Item_func_true(); // Always true
9464 }
9465
5/6
✓ Branch 0 taken 860343 times.
✓ Branch 1 taken 608147 times.
✓ Branch 2 taken 858047 times.
✓ Branch 3 taken 2301 times.
✓ Branch 4 taken 858056 times.
✗ Branch 5 not taken.
2326539 if (tmp || !cond || tab->type() == JT_REF ||
9466
8/8
✓ Branch 0 taken 1468490 times.
✓ Branch 1 taken 2357971 times.
✓ Branch 2 taken 467649 times.
✓ Branch 3 taken 390401 times.
✓ Branch 4 taken 9177 times.
✓ Branch 5 taken 458472 times.
✓ Branch 6 taken 3367990 times.
✓ Branch 7 taken 458472 times.
6153005 tab->type() == JT_REF_OR_NULL || tab->type() == JT_EQ_REF ||
9467 first_inner != NO_PLAN_IDX) {
9468
4/6
✓ Branch 0 taken 3367995 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 3367970 times.
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
3367990 DBUG_EXECUTE("where",
9469 print_where(thd, tmp, tab->table()->alias, QT_ORDINARY););
9470 /*
9471 If tab is an inner table of an outer join operation,
9472 add a match guard to the pushed down predicate.
9473 The guard will turn the predicate on only after
9474 the first match for outer tables is encountered.
9475 */
9476
4/4
✓ Branch 0 taken 2759839 times.
✓ Branch 1 taken 608152 times.
✓ Branch 2 taken 2357956 times.
✓ Branch 3 taken 401883 times.
3367991 if (cond && tmp) {
9477 /*
9478 Because of GroupIndexSkipScanIterator there may be a select without
9479 a cond, so neutralize the hack above.
9480 */
9481
2/4
✓ Branch 0 taken 2357941 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2357941 times.
2357956 if (!(tmp = add_found_match_trig_cond(join, first_inner, tmp,
9482 NO_PLAN_IDX)))
9483 return true;
9484 2357941 tab->set_condition(tmp);
9485 } else {
9486 1010035 tab->set_condition(nullptr);
9487 }
9488
9489
4/6
✓ Branch 0 taken 3367996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 3367971 times.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
3367999 DBUG_EXECUTE("where",
9490 print_where(thd, tmp, tab->table()->alias, QT_ORDINARY););
9491
9492
2/2
✓ Branch 0 taken 32149 times.
✓ Branch 1 taken 3335849 times.
3367996 if (tab->range_scan()) {
9493
3/6
✓ Branch 0 taken 32149 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32149 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 32149 times.
32149 if (tab->needed_reg.is_clear_all() && tab->type() != JT_CONST) {
9494 /*
9495 We keep (for now) the QUICK AM calculated in
9496 get_quick_record_count().
9497 */
9498 } else {
9499 destroy(tab->range_scan());
9500 tab->set_range_scan(nullptr);
9501 }
9502 }
9503
9504
4/4
✓ Branch 0 taken 2060217 times.
✓ Branch 1 taken 31031 times.
✓ Branch 2 taken 2059105 times.
✓ Branch 3 taken 1118 times.
7519466 if ((tab->type() == JT_ALL || tab->type() == JT_RANGE ||
9505
6/6
✓ Branch 0 taken 2091245 times.
✓ Branch 1 taken 1276752 times.
✓ Branch 2 taken 37931 times.
✓ Branch 3 taken 2021168 times.
✓ Branch 4 taken 1345814 times.
✓ Branch 5 taken 2022186 times.
8834151 tab->type() == JT_INDEX_MERGE || tab->type() == JT_INDEX_SCAN) &&
9506
2/2
✓ Branch 0 taken 1345815 times.
✓ Branch 1 taken 1017 times.
1346832 tab->use_quick != QS_RANGE) {
9507 /*
9508 We plan to scan (table/index/range scan).
9509 Check again if we should use an index. We can use an index if:
9510
9511 1a) There is a condition that range optimizer can work on, and
9512 1b) There are non-constant conditions on one or more keys, and
9513 1c) Some of the non-constant fields may have been read
9514 already. This may be the case if this is not the first
9515 table in the join OR this is a subselect with
9516 non-constant conditions referring to an outer table
9517 (dependent subquery)
9518 or,
9519 2a) There are conditions only relying on constants
9520 2b) This is the first non-constant table
9521 2c) There is a limit of rows to read that is lower than
9522 the fanout for this table, predicate filters included
9523 (i.e., the estimated number of rows that will be
9524 produced for this table per row combination of
9525 previous tables)
9526 2d) The query is NOT run with FOUND_ROWS() (because in that
9527 case we have to scan through all rows to count them anyway)
9528 */
9529 enum {
9530 DONT_RECHECK,
9531 NOT_FIRST_TABLE,
9532 LOW_LIMIT
9533 1345814 } recheck_reason = DONT_RECHECK;
9534
9535
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1345815 times.
1345814 assert(tab->const_keys.is_subset(tab->keys()));
9536
9537 1345815 const join_type orig_join_type = tab->type();
9538 1345817 const AccessPath *const orig_range_scan = tab->range_scan();
9539
9540
2/2
✓ Branch 0 taken 63887 times.
✓ Branch 1 taken 673774 times.
737661 if (cond && // 1a
9541
6/6
✓ Branch 0 taken 737661 times.
✓ Branch 1 taken 608155 times.
✓ Branch 2 taken 2390 times.
✓ Branch 3 taken 61497 times.
✓ Branch 4 taken 61551 times.
✓ Branch 5 taken 1284263 times.
2085865 (tab->keys() != tab->const_keys) && // 1b
9542 2390 (i > 0 || // 1c
9543
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 2228 times.
2390 (join->query_block->master_query_expression()->item &&
9544
3/4
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 106 times.
162 cond->is_outer_reference())))
9545 61551 recheck_reason = NOT_FIRST_TABLE;
9546 1284263 else if (!tab->const_keys.is_clear_all() && // 2a
9547
2/2
✓ Branch 0 taken 197519 times.
✓ Branch 1 taken 502 times.
198021 i == join->const_tables && // 2b
9548 197519 (join->query_expression()->select_limit_cnt <
9549 197519 (tab->position()->rows_fetched *
9550
6/6
✓ Branch 0 taken 198021 times.
✓ Branch 1 taken 1086240 times.
✓ Branch 2 taken 2434 times.
✓ Branch 3 taken 195085 times.
✓ Branch 4 taken 2429 times.
✓ Branch 5 taken 1281832 times.
1484716 tab->position()->filter_effect)) && // 2c
9551
2/2
✓ Branch 0 taken 2429 times.
✓ Branch 1 taken 5 times.
2434 !join->calc_found_rows) // 2d
9552 2429 recheck_reason = LOW_LIMIT;
9553
9554 // Don't recheck if the storage engine does not support index access.
9555
2/2
✓ Branch 0 taken 307 times.
✓ Branch 1 taken 1345505 times.
1345812 if ((tab->table()->file->ha_table_flags() & HA_NO_INDEX_ACCESS) != 0)
9556 307 recheck_reason = DONT_RECHECK;
9557
9558
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 1345800 times.
1345812 if (tab->position()->sj_strategy == SJ_OPT_LOOSE_SCAN) {
9559 /*
9560 Semijoin loose scan has settled for a certain index-based access
9561 method with suitable characteristics, don't substitute it.
9562 */
9563 17 recheck_reason = DONT_RECHECK;
9564 }
9565
9566
2/2
✓ Branch 0 taken 63966 times.
✓ Branch 1 taken 1281851 times.
1345817 if (recheck_reason != DONT_RECHECK) {
9567
1/2
✓ Branch 0 taken 63966 times.
✗ Branch 1 not taken.
63966 Opt_trace_object trace_one_table(trace);
9568
1/2
✓ Branch 0 taken 63966 times.
✗ Branch 1 not taken.
63966 trace_one_table.add_utf8_table(tab->table_ref);
9569
1/2
✓ Branch 0 taken 63966 times.
✗ Branch 1 not taken.
63966 Opt_trace_object trace_table(trace, "rechecking_index_usage");
9570
2/2
✓ Branch 0 taken 61537 times.
✓ Branch 1 taken 2429 times.
63966 if (recheck_reason == NOT_FIRST_TABLE)
9571
1/2
✓ Branch 0 taken 61537 times.
✗ Branch 1 not taken.
61537 trace_table.add_alnum("recheck_reason", "not_first_table");
9572 else
9573
1/2
✓ Branch 0 taken 2429 times.
✗ Branch 1 not taken.
2429 trace_table.add_alnum("recheck_reason", "low_limit")
9574
1/2
✓ Branch 0 taken 2429 times.
✗ Branch 1 not taken.
2429 .add("limit", join->query_expression()->select_limit_cnt)
9575 2429 .add("row_estimate", tab->position()->rows_fetched *
9576
1/2
✓ Branch 0 taken 2429 times.
✗ Branch 1 not taken.
2429 tab->position()->filter_effect);
9577
9578 /* Join with outer join condition */
9579 63966 Item *orig_cond = tab->condition();
9580
1/2
✓ Branch 0 taken 63966 times.
✗ Branch 1 not taken.
63966 tab->and_with_condition(tab->join_cond());
9581
9582 /*
9583 We can't call sel->cond->fix_fields,
9584 as it will break tab->join_cond() if it's AND condition
9585 (fix_fields currently removes extra AND/OR levels).
9586 Yet attributes of the just built condition are not needed.
9587 Thus we call sel->cond->quick_fix_field for safety.
9588 */
9589
4/6
✓ Branch 0 taken 63580 times.
✓ Branch 1 taken 386 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 63580 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 63966 times.
63966 if (tab->condition() && !tab->condition()->fixed)
9590 tab->condition()->quick_fix_field();
9591
9592 63966 Key_map usable_keys = tab->keys();
9593 63966 enum_order interesting_order = ORDER_NOT_RELEVANT;
9594
9595
2/2
✓ Branch 0 taken 2429 times.
✓ Branch 1 taken 61537 times.
63966 if (recheck_reason == LOW_LIMIT) {
9596 2429 int read_direction = 0;
9597
9598 /*
9599 If the current plan is to use range, then check if the
9600 already selected index provides the order dictated by the
9601 ORDER BY clause.
9602 */
9603
6/6
✓ Branch 0 taken 1441 times.
✓ Branch 1 taken 988 times.
✓ Branch 2 taken 1439 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1439 times.
✓ Branch 5 taken 990 times.
3870 if (tab->range_scan() &&
9604 1441 used_index(tab->range_scan()) != MAX_KEY) {
9605 1439 const uint ref_key = used_index(tab->range_scan());
9606 bool skip_quick;
9607
1/2
✓ Branch 0 taken 1439 times.
✗ Branch 1 not taken.
1439 read_direction = test_if_order_by_key(
9608 &join->order, tab->table(), ref_key, nullptr, &skip_quick);
9609
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1439 times.
1439 if (skip_quick) read_direction = 0;
9610 /*
9611 If the index provides order there is no need to recheck
9612 index usage; we already know from the former call to
9613 test_quick_select() that a range scan on the chosen
9614 index is cheapest. Note that previous calls to
9615 test_quick_select() did not take order direction
9616 (ASC/DESC) into account, so in case of DESC ordering
9617 we still need to recheck.
9618 */
9619
4/4
✓ Branch 0 taken 747 times.
✓ Branch 1 taken 692 times.
✓ Branch 2 taken 692 times.
✓ Branch 3 taken 747 times.
2186 if (read_direction == 1 ||
9620
3/4
✓ Branch 0 taken 301 times.
✓ Branch 1 taken 446 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 301 times.
1048 (read_direction == -1 &&
9621 301 is_reverse_sorted_range(tab->range_scan()))) {
9622 692 recheck_reason = DONT_RECHECK;
9623 }
9624 }
9625 // We do a cost based search for an ordering index here. Do this
9626 // only if prefer_ordering_index switch is on or an index is
9627 // forced for order by
9628
4/4
✓ Branch 0 taken 1737 times.
✓ Branch 1 taken 692 times.
✓ Branch 2 taken 1735 times.
✓ Branch 3 taken 694 times.
4166 if (recheck_reason != DONT_RECHECK &&
9629
4/4
✓ Branch 0 taken 1735 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1733 times.
✓ Branch 3 taken 2 times.
3472 (tab->table()->force_index_order ||
9630 1735 thd->optimizer_switch_flag(
9631 OPTIMIZER_SWITCH_PREFER_ORDERING_INDEX))) {
9632 1735 int best_key = -1;
9633 ha_rows select_limit =
9634 1735 join->query_expression()->select_limit_cnt;
9635
9636 /* Use index specified in FORCE INDEX FOR ORDER BY, if any. */
9637
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1733 times.
1735 if (tab->table()->force_index_order)
9638 2 usable_keys.intersect(tab->table()->keys_in_use_for_order_by);
9639
9640 // Do a cost based search on the indexes that give sort order.
9641
1/2
✓ Branch 0 taken 1735 times.
✗ Branch 1 not taken.
1735 test_if_cheaper_ordering(
9642 tab, &join->order, tab->table(), usable_keys, -1,
9643 select_limit, &best_key, &read_direction, &select_limit);
9644
2/2
✓ Branch 0 taken 1062 times.
✓ Branch 1 taken 673 times.
1735 if (best_key < 0)
9645 1062 recheck_reason = DONT_RECHECK; // No usable keys
9646 else {
9647 // Only usable_key is the best_key chosen
9648 673 usable_keys.clear_all();
9649 673 usable_keys.set_bit(best_key);
9650 673 interesting_order =
9651
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 354 times.
673 (read_direction == -1 ? ORDER_DESC : ORDER_ASC);
9652 }
9653 }
9654 }
9655
9656 63966 bool search_if_impossible = recheck_reason != DONT_RECHECK;
9657
2/2
✓ Branch 0 taken 62212 times.
✓ Branch 1 taken 1754 times.
63966 if (search_if_impossible) {
9658
2/2
✓ Branch 0 taken 298 times.
✓ Branch 1 taken 61914 times.
62212 if (tab->range_scan()) {
9659 298 destroy(tab->range_scan());
9660 298 tab->set_type(JT_ALL);
9661 }
9662 AccessPath *range_scan;
9663 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
9664 62212 thd->variables.range_alloc_block_size);
9665 62212 search_if_impossible =
9666 124424 test_quick_select(
9667 thd, thd->mem_root, &temp_mem_root, usable_keys,
9668
1/2
✓ Branch 0 taken 62212 times.
✗ Branch 1 not taken.
62212 used_tables & ~tab->table_ref->map(), 0,
9669
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62212 times.
62212 join->calc_found_rows
9670 ? HA_POS_ERROR
9671 62212 : join->query_expression()->select_limit_cnt,
9672 false, // don't force quick range
9673 interesting_order, tab->table(),
9674 62212 tab->skip_records_in_range(), tab->condition(),
9675 62212 &tab->needed_reg, tab->table()->force_index,
9676 62212 join->query_block, &range_scan) < 0;
9677 62212 tab->set_range_scan(range_scan);
9678 62212 }
9679 63966 tab->set_condition(orig_cond);
9680
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63966 times.
63966 if (search_if_impossible) {
9681 /*
9682 Before reporting "Impossible WHERE" for the whole query
9683 we have to check isn't it only "impossible ON" instead
9684 */
9685 if (!tab->join_cond())
9686 return true; // No ON, so it's really "impossible WHERE"
9687 Opt_trace_object trace_without_on(trace, "without_ON_clause");
9688 if (tab->range_scan()) {
9689 destroy(tab->range_scan());
9690 tab->set_type(JT_ALL);
9691 }
9692 AccessPath *range_scan;
9693 MEM_ROOT temp_mem_root(key_memory_test_quick_select_exec,
9694 thd->variables.range_alloc_block_size);
9695 const bool impossible_where =
9696 test_quick_select(
9697 thd, thd->mem_root, &temp_mem_root, tab->keys(),
9698 used_tables & ~tab->table_ref->map(), 0,
9699 join->calc_found_rows
9700 ? HA_POS_ERROR
9701 : join->query_expression()->select_limit_cnt,
9702 false, // don't force quick range
9703 ORDER_NOT_RELEVANT, tab->table(),
9704 tab->skip_records_in_range(), tab->condition(),
9705 &tab->needed_reg, tab->table()->force_index,
9706 join->query_block, &range_scan) < 0;
9707 tab->set_range_scan(range_scan);
9708 if (impossible_where) return true; // Impossible WHERE
9709 }
9710
9711 /*
9712 Access method changed. This is after deciding join order
9713 and access method for all other tables so the info
9714 updated below will not have any effect on the execution
9715 plan.
9716 */
9717
2/2
✓ Branch 0 taken 1536 times.
✓ Branch 1 taken 62430 times.
63966 if (tab->range_scan())
9718
1/2
✓ Branch 0 taken 1536 times.
✗ Branch 1 not taken.
1536 tab->set_type(calc_join_type(tab->range_scan()));
9719
9720
2/4
✓ Branch 0 taken 63966 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 63966 times.
✗ Branch 3 not taken.
63966 } // end of "if (recheck_reason != DONT_RECHECK)"
9721
9722
4/4
✓ Branch 0 taken 1325746 times.
✓ Branch 1 taken 20072 times.
✓ Branch 2 taken 20487 times.
✓ Branch 3 taken 1325330 times.
2671562 if (!tab->table()->quick_keys.is_subset(tab->checked_keys) ||
9723
2/2
✓ Branch 0 taken 415 times.
✓ Branch 1 taken 1325330 times.
1325746 !tab->needed_reg.is_subset(tab->checked_keys)) {
9724 20487 tab->keys().merge(tab->table()->quick_keys);
9725 20487 tab->keys().merge(tab->needed_reg);
9726
9727 /*
9728 The logic below for assigning tab->use_quick is strange.
9729 It bases the decision of which access method to use
9730 (dynamic range, range, scan) based on seemingly
9731 unrelated information like the presence of another index
9732 with too bad selectivity to be used.
9733
9734 Consider the following scenario:
9735
9736 The join optimizer has decided to use join order
9737 (t1,t2), and 'tab' is currently t2. Further, assume that
9738 there is a join condition between t1 and t2 using some
9739 range operator (e.g. "t1.x < t2.y").
9740
9741 It has been decided that a table scan is best for t2.
9742 make_join_query_block() then reran the range optimizer a few
9743 lines up because there is an index 't2.good_idx'
9744 covering the t2.y column. If 'good_idx' is the only
9745 index in t2, the decision below will be to use dynamic
9746 range. However, if t2 also has another index 't2.other'
9747 which the range access method can be used on but
9748 selectivity is bad (#rows estimate is high), then table
9749 scan is chosen instead.
9750
9751 Thus, the choice of DYNAMIC RANGE vs SCAN depends on the
9752 presence of an index that has so bad selectivity that it
9753 will not be used anyway.
9754 */
9755
6/6
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 20063 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 416 times.
✓ Branch 4 taken 416 times.
✓ Branch 5 taken 20071 times.
20919 if (!tab->needed_reg.is_clear_all() &&
9756
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
432 (tab->table()->quick_keys.is_clear_all() ||
9757 8 (tab->range_scan() &&
9758 (tab->range_scan()->num_output_rows >= 100.0)))) {
9759 416 tab->use_quick = QS_DYNAMIC_RANGE;
9760 416 tab->set_type(JT_ALL);
9761 } else
9762 20071 tab->use_quick = QS_RANGE;
9763 }
9764
9765
6/6
✓ Branch 0 taken 1345533 times.
✓ Branch 1 taken 279 times.
✓ Branch 2 taken 286 times.
✓ Branch 3 taken 1345252 times.
✓ Branch 4 taken 565 times.
✓ Branch 5 taken 1345252 times.
2691355 if (tab->type() != orig_join_type ||
9766 1345533 tab->range_scan() != orig_range_scan) // Access method changed
9767 565 tab->position()->filter_effect = COND_FILTER_STALE;
9768 }
9769 }
9770
9771
2/4
✓ Branch 0 taken 3826455 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3826455 times.
3826475 if (join->attach_join_conditions(i)) return true;
9772 }
9773
1/2
✓ Branch 0 taken 1900533 times.
✗ Branch 1 not taken.
1900549 trace_attached_comp.end();
9774
9775 /*
9776 In outer joins the loop above, in iteration for table #i, may push
9777 conditions to a table before #i. Thus, the processing below has to be in
9778 a separate loop:
9779 */
9780 Opt_trace_array trace_attached_summary(trace,
9781
1/2
✓ Branch 0 taken 1900537 times.
✗ Branch 1 not taken.
1900533 "attached_conditions_summary");
9782
2/2
✓ Branch 0 taken 6381711 times.
✓ Branch 1 taken 1900550 times.
8282261 for (uint i = join->const_tables; i < join->tables; i++) {
9783 6381711 JOIN_TAB *const tab = join->best_ref[i];
9784
2/2
✓ Branch 0 taken 2555260 times.
✓ Branch 1 taken 3826458 times.
6381711 if (!tab->table()) continue;
9785 3826458 Item *const tab_cond = tab->condition();
9786
1/2
✓ Branch 0 taken 3826463 times.
✗ Branch 1 not taken.
3826466 Opt_trace_object trace_one_table(trace);
9787
2/4
✓ Branch 0 taken 3826468 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3826468 times.
✗ Branch 3 not taken.
3826463 trace_one_table.add_utf8_table(tab->table_ref).add("attached", tab_cond);
9788
6/6
✓ Branch 0 taken 2759240 times.
✓ Branch 1 taken 1067228 times.
✓ Branch 2 taken 2452 times.
✓ Branch 3 taken 2756788 times.
✓ Branch 4 taken 2452 times.
✓ Branch 5 taken 3824016 times.
3826468 if (tab_cond && tab_cond->has_subquery()) // traverse only if needed
9789 {
9790 /*
9791 Why we pass walk_subquery=false: imagine
9792 WHERE t1.col IN (SELECT * FROM t2
9793 WHERE t2.col IN (SELECT * FROM t3)
9794 and tab==t1. The grandchild subquery (SELECT * FROM t3) should not
9795 be marked as "in condition of t1" but as "in condition of t2", for
9796 correct calculation of the number of its executions.
9797 */
9798 2452 std::pair<Query_block *, int> pair_object(join->query_block, i);
9799
1/2
✓ Branch 0 taken 2452 times.
✗ Branch 1 not taken.
2452 tab_cond->walk(&Item::inform_item_in_cond_of_tab, enum_walk::POSTFIX,
9800 pointer_cast<uchar *>(&pair_object));
9801 }
9802 3826468 }
9803
4/6
✓ Branch 0 taken 1900532 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1900536 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1900537 times.
✗ Branch 5 not taken.
1900554 }
9804 1900537 return false;
9805 1903458 }
9806
9807 /**
9808 Remove the following expressions from ORDER BY and GROUP BY:
9809 Constant expressions @n
9810 Expression that only uses tables that are of type EQ_REF and the reference
9811 is in the ORDER list or if all refereed tables are of the above type.
9812
9813 In the following, the X field can be removed:
9814 @code
9815 SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
9816 SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
9817 @endcode
9818
9819 These can't be optimized:
9820 @code
9821 SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
9822 SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
9823 SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
9824 @endcode
9825
9826 @param join join object
9827 @param start_order clause being analyzed (ORDER BY, GROUP BY...)
9828 @param tab table
9829 @param cached_eq_ref_tables bitmap: bit Z is set if the table of map Z
9830 was already the subject of an eq_ref_table() call for the same clause; then
9831 the return value of this previous call can be found at bit Z of
9832 'eq_ref_tables'
9833 @param eq_ref_tables see above.
9834 */
9835
9836 418840 static bool eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab,
9837 table_map *cached_eq_ref_tables,
9838 table_map *eq_ref_tables) {
9839 /* We can skip const tables only if not an outer table */
9840
6/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 418830 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 418839 times.
418840 if (tab->type() == JT_CONST && tab->first_inner() == NO_PLAN_IDX) return true;
9841
6/6
✓ Branch 0 taken 116560 times.
✓ Branch 1 taken 302279 times.
✓ Branch 2 taken 277 times.
✓ Branch 3 taken 116283 times.
✓ Branch 4 taken 302556 times.
✓ Branch 5 taken 116283 times.
418839 if (tab->type() != JT_EQ_REF || tab->table()->is_nullable()) return false;
9842
9843 116283 const table_map map = tab->table_ref->map();
9844 116283 uint found = 0;
9845
9846 116335 for (Item **ref_item = tab->ref().items,
9847 116283 **end = ref_item + tab->ref().key_parts;
9848
2/2
✓ Branch 0 taken 116283 times.
✓ Branch 1 taken 52 times.
116335 ref_item != end; ref_item++) {
9849
1/2
✓ Branch 0 taken 116283 times.
✗ Branch 1 not taken.
116283 if (!(*ref_item)->const_item()) { // Not a const ref
9850 ORDER *order;
9851
2/2
✓ Branch 0 taken 321087 times.
✓ Branch 1 taken 116234 times.
437321 for (order = start_order; order; order = order->next) {
9852
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 321038 times.
321087 if ((*ref_item)->eq(order->item[0], false)) break;
9853 }
9854
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 116234 times.
116283 if (order) {
9855
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
49 if (!(order->used & map)) {
9856 49 found++;
9857 49 order->used |= map;
9858 }
9859 49 continue; // Used in ORDER BY
9860 }
9861
2/2
✓ Branch 0 taken 116231 times.
✓ Branch 1 taken 3 times.
116234 if (!only_eq_ref_tables(join, start_order, (*ref_item)->used_tables(),
9862 cached_eq_ref_tables, eq_ref_tables))
9863 116231 return false;
9864 }
9865 }
9866 /* Check that there was no reference to table before sort order */
9867
3/4
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 85 times.
✗ Branch 3 not taken.
95 for (; found && start_order; start_order = start_order->next) {
9868
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 78 times.
85 if (start_order->used & map) {
9869 7 found--;
9870 7 continue;
9871 }
9872
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 36 times.
78 if (start_order->depend_map & map) return false;
9873 }
9874 10 return true;
9875 }
9876
9877 /// @see eq_ref_table()
9878 537768 static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables,
9879 table_map *cached_eq_ref_tables,
9880 table_map *eq_ref_tables) {
9881 537768 tables &= ~PSEUDO_TABLE_BITS;
9882
2/2
✓ Branch 0 taken 748789 times.
✓ Branch 1 taken 11 times.
748800 for (JOIN_TAB **tab = join->map2table; tables; tab++, tables >>= 1) {
9883
2/2
✓ Branch 0 taken 537768 times.
✓ Branch 1 taken 211021 times.
748789 if (tables & 1) {
9884 537768 const table_map map = (*tab)->table_ref->map();
9885 bool is_eq_ref;
9886
2/2
✓ Branch 0 taken 118928 times.
✓ Branch 1 taken 418840 times.
537768 if (*cached_eq_ref_tables & map) // then there exists a cached bit
9887 118928 is_eq_ref = *eq_ref_tables & map;
9888 else {
9889 418840 is_eq_ref = eq_ref_table(join, order, *tab, cached_eq_ref_tables,
9890 eq_ref_tables);
9891
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 418829 times.
418840 if (is_eq_ref)
9892 11 *eq_ref_tables |= map;
9893 else
9894 418829 *eq_ref_tables &= ~map;
9895 418840 *cached_eq_ref_tables |= map; // now there exists a cached bit
9896 }
9897
2/2
✓ Branch 0 taken 537757 times.
✓ Branch 1 taken 11 times.
537768 if (!is_eq_ref) return false;
9898 }
9899 }
9900 11 return true;
9901 }
9902
9903 /**
9904 Check if an expression in ORDER BY or GROUP BY is a duplicate of a
9905 preceding expression.
9906
9907 @param first_order the first expression in the ORDER BY or
9908 GROUP BY clause
9909 @param possible_dup the expression that might be a duplicate of
9910 another expression preceding it the ORDER BY
9911 or GROUP BY clause
9912
9913 @returns true if possible_dup is a duplicate, false otherwise
9914 */
9915 1022444 static bool duplicate_order(const ORDER *first_order,
9916 const ORDER *possible_dup) {
9917 const ORDER *order;
9918
1/2
✓ Branch 0 taken 2660974 times.
✗ Branch 1 not taken.
2660974 for (order = first_order; order; order = order->next) {
9919
2/2
✓ Branch 0 taken 1022282 times.
✓ Branch 1 taken 1638692 times.
2660974 if (order == possible_dup) {
9920 // all expressions preceding possible_dup have been checked.
9921 1022282 return false;
9922 } else {
9923 1638692 const Item *it1 = order->item[0]->real_item();
9924 1638692 const Item *it2 = possible_dup->item[0]->real_item();
9925
9926
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 1638530 times.
1638692 if (it1->eq(it2, false)) return true;
9927 }
9928 }
9929 return false;
9930 }
9931
9932 /**
9933 Remove all constants and check if ORDER only contains simple
9934 expressions.
9935
9936 simple_order is set to true if sort_order only uses fields from head table
9937 and the head table is not a LEFT JOIN table.
9938
9939 @param first_order List of GROUP BY or ORDER BY sub-clauses.
9940 @param cond WHERE condition.
9941 @param change If true, remove sub-clauses that need not be evaluated.
9942 If this is not set, then only simple_order is calculated.
9943 @param[out] simple_order Set to true if we are only using simple expressions.
9944 @param group_by True if first_order represents a grouping operation.
9945
9946 @returns new sort order, after const elimination (when change is true).
9947 */
9948
9949 3801040 ORDER *JOIN::remove_const(ORDER *first_order, Item *cond, bool change,
9950 bool *simple_order, bool group_by) {
9951
1/2
✓ Branch 0 taken 3801073 times.
✗ Branch 1 not taken.
3801040 DBUG_TRACE;
9952
9953
4/6
✓ Branch 0 taken 3801074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3801074 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3801070 times.
✓ Branch 5 taken 4 times.
3801073 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
9954
9955
2/2
✓ Branch 0 taken 173286 times.
✓ Branch 1 taken 3627787 times.
3801069 if (plan_is_const())
9956
2/2
✓ Branch 0 taken 173278 times.
✓ Branch 1 taken 8 times.
173286 return change ? nullptr : first_order; // No need to sort
9957
9958 3627787 Opt_trace_context *const trace = &thd->opt_trace;
9959
1/2
✓ Branch 0 taken 3627780 times.
✗ Branch 1 not taken.
3627787 Opt_trace_disable_I_S trace_disabled(trace, first_order == nullptr);
9960 Opt_trace_object trace_simpl(
9961
3/4
✓ Branch 0 taken 1813895 times.
✓ Branch 1 taken 1813885 times.
✓ Branch 2 taken 3627785 times.
✗ Branch 3 not taken.
3627780 trace, group_by ? "simplifying_group_by" : "simplifying_order_by");
9962
2/2
✓ Branch 0 taken 5238 times.
✓ Branch 1 taken 3622550 times.
3627785 if (trace->is_started()) {
9963 5238 String str;
9964 5238 Query_block::print_order(
9965
1/2
✓ Branch 0 taken 5238 times.
✗ Branch 1 not taken.
5238 thd, &str, first_order,
9966 enum_query_type(QT_TO_SYSTEM_CHARSET | QT_SHOW_SELECT_NUMBER |
9967 QT_NO_DEFAULT_DB));
9968
1/2
✓ Branch 0 taken 5238 times.
✗ Branch 1 not taken.
5238 trace_simpl.add_utf8("original_clause", str.ptr(), str.length());
9969 5238 }
9970
1/2
✓ Branch 0 taken 3627786 times.
✗ Branch 1 not taken.
3627788 Opt_trace_array trace_each_item(trace, "items");
9971
9972 3627786 JOIN_TAB *const first_tab = best_ref[const_tables];
9973 3627786 table_map first_table = first_tab->table_ref->map();
9974 3627789 table_map not_const_tables = ~const_table_map;
9975 table_map ref;
9976 // Caches to avoid repeating eq_ref_table() calls, @see eq_ref_table()
9977 3627789 table_map eq_ref_tables = 0, cached_eq_ref_tables = 0;
9978
9979 3627789 ORDER **prev_ptr = &first_order;
9980 3627789 *simple_order = !first_tab->join_cond();
9981
9982 // De-optimization in conjunction with window functions
9983
4/4
✓ Branch 0 taken 1813896 times.
✓ Branch 1 taken 1813893 times.
✓ Branch 2 taken 1260 times.
✓ Branch 3 taken 1812636 times.
3627789 if (group_by && m_windows.elements > 0) *simple_order = false;
9984
9985
1/2
✓ Branch 0 taken 3627788 times.
✗ Branch 1 not taken.
3627789 update_depend_map(first_order);
9986
9987
2/2
✓ Branch 0 taken 1023216 times.
✓ Branch 1 taken 3627787 times.
4651003 for (ORDER *order = first_order; order; order = order->next) {
9988
1/2
✓ Branch 0 taken 1023216 times.
✗ Branch 1 not taken.
1023216 Opt_trace_object trace_one_item(trace);
9989
1/2
✓ Branch 0 taken 1023216 times.
✗ Branch 1 not taken.
1023216 trace_one_item.add("item", order->item[0]);
9990
1/2
✓ Branch 0 taken 1023216 times.
✗ Branch 1 not taken.
1023216 table_map order_tables = order->item[0]->used_tables();
9991
9992
6/6
✓ Branch 0 taken 1022897 times.
✓ Branch 1 taken 318 times.
✓ Branch 2 taken 1022834 times.
✓ Branch 3 taken 64 times.
✓ Branch 4 taken 393 times.
✓ Branch 5 taken 1022823 times.
2046050 if (order->item[0]->has_aggregation() || order->item[0]->has_wf() ||
9993 /*
9994 If the outer table of an outer join is const (either by itself or
9995 after applying WHERE condition), grouping on a field from such a
9996 table will be optimized away and filesort without temporary table
9997 will be used unless we prevent that now. Filesort is not fit to
9998 handle joins and the join condition is not applied. We can't detect
9999 the case without an expensive test, however, so we force temporary
10000 table for all queries containing more than one table, ROLLUP, and an
10001 outer join.
10002 */
10003
4/4
✓ Branch 0 taken 461806 times.
✓ Branch 1 taken 561028 times.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 461757 times.
1022834 (primary_tables > 1 && rollup_state == RollupState::INITED &&
10004
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 38 times.
49 query_block->outer_join)) {
10005 393 *simple_order = false; // Must use a temporary table to sort
10006
4/4
✓ Branch 0 taken 379 times.
✓ Branch 1 taken 1022444 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 1022446 times.
1023202 } else if ((order_tables & not_const_tables) == 0 &&
10007
3/4
✓ Branch 0 taken 379 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 2 times.
379 evaluate_during_optimization(order->item[0], query_block)) {
10008
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 340 times.
377 if (order->item[0]->has_subquery()) {
10009
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 5 times.
37 if (!thd->lex->is_explain()) {
10010
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 Opt_trace_array trace_subselect(trace, "subselect_evaluation");
10011 32 String str;
10012
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 order->item[0]->val_str(&str);
10013 32 }
10014
1/2
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
37 order->item[0]->mark_subqueries_optimized_away();
10015 }
10016
1/2
✓ Branch 0 taken 377 times.
✗ Branch 1 not taken.
377 trace_one_item.add("uses_only_constant_tables", true);
10017 377 continue; // skip const item
10018
3/4
✓ Branch 0 taken 1022444 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 162 times.
✓ Branch 3 taken 1022282 times.
1022823 } else if (duplicate_order(first_order, order)) {
10019 /*
10020 If 'order' is a duplicate of an expression earlier in the
10021 ORDER/GROUP BY sequence, it can be removed from the ORDER BY
10022 or GROUP BY clause.
10023 */
10024
1/2
✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
162 trace_one_item.add("duplicate_item", true);
10025 162 continue;
10026
6/6
✓ Branch 0 taken 993860 times.
✓ Branch 1 taken 28422 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 993835 times.
✓ Branch 4 taken 25 times.
✓ Branch 5 taken 1022257 times.
1022282 } else if (order->in_field_list && order->item[0]->has_subquery()) {
10027 /*
10028 If the order item is a subquery that is also in the field
10029 list, a temp table should be used to avoid evaluating the
10030 subquery for each row both when a) creating a sort index and
10031 b) getting the value.
10032 Example: "SELECT (SELECT ... ) as a ... GROUP BY a;"
10033 */
10034 25 *simple_order = false;
10035
2/2
✓ Branch 0 taken 1372 times.
✓ Branch 1 taken 1020885 times.
1022257 } else if (order_tables & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT)) {
10036 1372 *simple_order = false;
10037 } else {
10038
7/8
✓ Branch 0 taken 616697 times.
✓ Branch 1 taken 404188 times.
✓ Branch 2 taken 616697 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16087 times.
✓ Branch 5 taken 600610 times.
✓ Branch 6 taken 16087 times.
✓ Branch 7 taken 1004798 times.
1020885 if (cond != nullptr && check_field_is_const(cond, order->item[0])) {
10039
1/2
✓ Branch 0 taken 16087 times.
✗ Branch 1 not taken.
16087 trace_one_item.add("equals_constant_in_where", true);
10040 16087 continue;
10041 }
10042
2/2
✓ Branch 0 taken 421716 times.
✓ Branch 1 taken 583082 times.
1004798 if ((ref = order_tables & (not_const_tables ^ first_table))) {
10043
4/4
✓ Branch 0 taken 421534 times.
✓ Branch 1 taken 182 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 421708 times.
843250 if (!(order_tables & first_table) &&
10044
3/4
✓ Branch 0 taken 421534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 421526 times.
421534 only_eq_ref_tables(this, first_order, ref, &cached_eq_ref_tables,
10045 &eq_ref_tables)) {
10046
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 trace_one_item.add("eq_ref_to_preceding_items", true);
10047 8 continue;
10048 }
10049 421708 *simple_order = false; // Must do a temp table to sort
10050 }
10051 }
10052
2/2
✓ Branch 0 taken 1006057 times.
✓ Branch 1 taken 523 times.
1006580 if (change) *prev_ptr = order; // use this entry
10053 1006580 prev_ptr = &order->next;
10054
2/2
✓ Branch 0 taken 1006581 times.
✓ Branch 1 taken 16634 times.
1023214 }
10055
2/2
✓ Branch 0 taken 3627112 times.
✓ Branch 1 taken 675 times.
3627787 if (change) *prev_ptr = nullptr;
10056
2/2
✓ Branch 0 taken 2983617 times.
✓ Branch 1 taken 644170 times.
3627787 if (prev_ptr == &first_order) // Nothing to sort/group
10057 2983617 *simple_order = true;
10058
5/8
✓ Branch 0 taken 3627780 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3627785 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✓ Branch 5 taken 3627735 times.
✓ Branch 6 taken 50 times.
✗ Branch 7 not taken.
3627787 DBUG_PRINT("exit", ("simple_order: %d", (int)*simple_order));
10059
10060
1/2
✓ Branch 0 taken 3627784 times.
✗ Branch 1 not taken.
3627785 trace_each_item.end();
10061
1/2
✓ Branch 0 taken 3627781 times.
✗ Branch 1 not taken.
3627784 trace_simpl.add("resulting_clause_is_simple", *simple_order);
10062
6/6
✓ Branch 0 taken 5238 times.
✓ Branch 1 taken 3622548 times.
✓ Branch 2 taken 5232 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 5232 times.
✓ Branch 5 taken 3622554 times.
3627781 if (trace->is_started() && change) {
10063 5232 String str;
10064 5232 Query_block::print_order(
10065
1/2
✓ Branch 0 taken 5232 times.
✗ Branch 1 not taken.
5232 thd, &str, first_order,
10066 enum_query_type(QT_TO_SYSTEM_CHARSET | QT_SHOW_SELECT_NUMBER |
10067 QT_NO_DEFAULT_DB));
10068
1/2
✓ Branch 0 taken 5232 times.
✗ Branch 1 not taken.
5232 trace_simpl.add_utf8("resulting_clause", str.ptr(), str.length());
10069 5232 }
10070
10071 3627786 return first_order;
10072 3801072 }
10073
10074 /**
10075 Optimize conditions by
10076
10077 a) applying transitivity to build multiple equality predicates
10078 (MEP): if x=y and y=z the MEP x=y=z is built.
10079 b) apply constants where possible. If the value of x is known to be
10080 42, x is replaced with a constant of value 42. By transitivity, this
10081 also applies to MEPs, so the MEP in a) will become 42=x=y=z.
10082 c) remove conditions that are always false or always true
10083
10084 @param thd Thread handler
10085 @param[in,out] cond WHERE or HAVING condition to optimize
10086 @param[out] cond_equal The built multiple equalities
10087 @param join_list list of join operations with join conditions
10088 = NULL: Called for HAVING condition
10089 @param[out] cond_value Not changed if cond was empty
10090 COND_TRUE if cond is always true
10091 COND_FALSE if cond is impossible
10092 COND_OK otherwise
10093
10094
10095 @returns false if success, true if error
10096 */
10097
10098 1769410 bool optimize_cond(THD *thd, Item **cond, COND_EQUAL **cond_equal,
10099 mem_root_deque<TABLE_LIST *> *join_list,
10100 Item::cond_result *cond_value) {
10101
1/2
✓ Branch 0 taken 1769489 times.
✗ Branch 1 not taken.
1769410 DBUG_TRACE;
10102 1769489 Opt_trace_context *const trace = &thd->opt_trace;
10103
10104
1/2
✓ Branch 0 taken 1769462 times.
✗ Branch 1 not taken.
1769489 Opt_trace_object trace_wrapper(trace);
10105
1/2
✓ Branch 0 taken 1769491 times.
✗ Branch 1 not taken.
1769462 Opt_trace_object trace_cond(trace, "condition_processing");
10106
3/4
✓ Branch 0 taken 1765525 times.
✓ Branch 1 taken 3966 times.
✓ Branch 2 taken 1769468 times.
✗ Branch 3 not taken.
1769491 trace_cond.add_alnum("condition", join_list ? "WHERE" : "HAVING");
10107
1/2
✓ Branch 0 taken 1769483 times.
✗ Branch 1 not taken.
1769468 trace_cond.add("original_condition", *cond);
10108
1/2
✓ Branch 0 taken 1769482 times.
✗ Branch 1 not taken.
1769483 Opt_trace_array trace_steps(trace, "steps");
10109
10110 /*
10111 Enter this function
10112 a) For a WHERE condition or a query having outer join.
10113 b) For a HAVING condition.
10114 */
10115
3/4
✓ Branch 0 taken 3940 times.
✓ Branch 1 taken 1765542 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3940 times.
1769482 assert(*cond || join_list);
10116
10117 /*
10118 Build all multiple equality predicates and eliminate equality
10119 predicates that can be inferred from these multiple equalities.
10120 For each reference of a field included into a multiple equality
10121 that occurs in a function set a pointer to the multiple equality
10122 predicate. Substitute a constant instead of this field if the
10123 multiple equality contains a constant.
10124 This is performed for the WHERE condition and any join conditions, but
10125 not for the HAVING condition.
10126 */
10127
2/2
✓ Branch 0 taken 1765518 times.
✓ Branch 1 taken 3964 times.
1769482 if (join_list) {
10128
1/2
✓ Branch 0 taken 1765529 times.
✗ Branch 1 not taken.
1765518 Opt_trace_object step_wrapper(trace);
10129
1/2
✓ Branch 0 taken 1765529 times.
✗ Branch 1 not taken.
1765529 step_wrapper.add_alnum("transformation", "equality_propagation");
10130 {
10131 Opt_trace_disable_I_S disable_trace_wrapper(
10132
5/6
✓ Branch 0 taken 1761562 times.
✓ Branch 1 taken 3967 times.
✓ Branch 2 taken 1757271 times.
✓ Branch 3 taken 4270 times.
✓ Branch 4 taken 1765471 times.
✗ Branch 5 not taken.
1765529 trace, !(*cond && (*cond)->has_subquery()));
10133
1/2
✓ Branch 0 taken 1765518 times.
✗ Branch 1 not taken.
1765471 Opt_trace_array trace_subselect(trace, "subselect_evaluation");
10134
3/4
✓ Branch 0 taken 1765527 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1765526 times.
1765518 if (build_equal_items(thd, *cond, cond, nullptr, true, join_list,
10135 cond_equal))
10136 1 return true;
10137
2/4
✓ Branch 0 taken 1765464 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1765482 times.
✗ Branch 3 not taken.
1765524 }
10138
1/2
✓ Branch 0 taken 1765489 times.
✗ Branch 1 not taken.
1765482 step_wrapper.add("resulting_condition", *cond);
10139
2/2
✓ Branch 0 taken 1765504 times.
✓ Branch 1 taken 2 times.
1765487 }
10140 /*
10141 change field = field to field = const for each found field = const
10142 Note: Since we disable multi-equalities in the hypergraph optimizer for now,
10143 we also cannot run this optimization; it causes spurious “Impossible WHERE”
10144 in e.g. main.select_none.
10145 */
10146
4/4
✓ Branch 0 taken 1765536 times.
✓ Branch 1 taken 3932 times.
✓ Branch 2 taken 1765509 times.
✓ Branch 3 taken 27 times.
1769468 if (*cond && !thd->lex->using_hypergraph_optimizer) {
10147
1/2
✓ Branch 0 taken 1765511 times.
✗ Branch 1 not taken.
1765509 Opt_trace_object step_wrapper(trace);
10148
1/2
✓ Branch 0 taken 1765515 times.
✗ Branch 1 not taken.
1765511 step_wrapper.add_alnum("transformation", "constant_propagation");
10149 {
10150 Opt_trace_disable_I_S disable_trace_wrapper(trace,
10151
1/2
✓ Branch 0 taken 1765508 times.
✗ Branch 1 not taken.
1765515 !(*cond)->has_subquery());
10152
1/2
✓ Branch 0 taken 1765504 times.
✗ Branch 1 not taken.
1765508 Opt_trace_array trace_subselect(trace, "subselect_evaluation");
10153
3/4
✓ Branch 0 taken 1765430 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1765429 times.
1765504 if (propagate_cond_constants(thd, nullptr, *cond, *cond)) return true;
10154
3/4
✓ Branch 0 taken 1765460 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1765516 times.
✓ Branch 3 taken 9 times.
1765429 }
10155
1/2
✓ Branch 0 taken 1765525 times.
✗ Branch 1 not taken.
1765516 step_wrapper.add("resulting_condition", *cond);
10156
2/2
✓ Branch 0 taken 1765511 times.
✓ Branch 1 taken 2 times.
1765534 }
10157
10158 /*
10159 Remove all instances of item == item
10160 Remove all and-levels where CONST item != CONST item
10161 */
10162
4/6
✓ Branch 0 taken 1769488 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 1769478 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
1769470 DBUG_EXECUTE("where",
10163 print_where(thd, *cond, "after const change", QT_ORDINARY););
10164
2/2
✓ Branch 0 taken 1765543 times.
✓ Branch 1 taken 3945 times.
1769488 if (*cond) {
10165
1/2
✓ Branch 0 taken 1765551 times.
✗ Branch 1 not taken.
1765543 Opt_trace_object step_wrapper(trace);
10166
1/2
✓ Branch 0 taken 1765555 times.
✗ Branch 1 not taken.
1765551 step_wrapper.add_alnum("transformation", "trivial_condition_removal");
10167 {
10168 Opt_trace_disable_I_S disable_trace_wrapper(trace,
10169
1/2
✓ Branch 0 taken 1765553 times.
✗ Branch 1 not taken.
1765555 !(*cond)->has_subquery());
10170
1/2
✓ Branch 0 taken 1765546 times.
✗ Branch 1 not taken.
1765553 Opt_trace_array trace_subselect(trace, "subselect_evaluation");
10171
3/4
✓ Branch 0 taken 1765454 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 1765439 times.
1765546 if (remove_eq_conds(thd, *cond, cond, cond_value)) return true;
10172
4/4
✓ Branch 0 taken 1765469 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 1765523 times.
✓ Branch 3 taken 18 times.
1765469 }
10173
1/2
✓ Branch 0 taken 1765524 times.
✗ Branch 1 not taken.
1765523 step_wrapper.add("resulting_condition", *cond);
10174
2/2
✓ Branch 0 taken 1765520 times.
✓ Branch 1 taken 14 times.
1765542 }
10175
3/4
✓ Branch 0 taken 1769465 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1769459 times.
1769465 if (thd->is_error()) return true;
10176 1769459 return false;
10177 1769483 }
10178
10179 /**
10180 Checks if a condition can be evaluated during constant folding. It can be
10181 evaluated if it is constant during execution and not expensive to evaluate. If
10182 it contains a subquery, it should not be evaluated if the option
10183 OPTION_NO_SUBQUERY_DURING_OPTIMIZATION is active.
10184 */
10185 15456165 static bool can_evaluate_condition(THD *thd, Item *condition) {
10186
4/4
✓ Branch 0 taken 21569 times.
✓ Branch 1 taken 15434669 times.
✓ Branch 2 taken 21527 times.
✓ Branch 3 taken 42 times.
15477698 return condition->const_for_execution() && !condition->is_expensive() &&
10187
2/2
✓ Branch 0 taken 21525 times.
✓ Branch 1 taken 8 times.
21527 evaluate_during_optimization(condition,
10188 15477771 thd->lex->current_query_block());
10189 }
10190
10191 /**
10192 Calls fold_condition. If that made the condition constant for execution,
10193 simplify and fold again. @see fold_condition() for arguments.
10194 */
10195 8634525 static bool fold_condition_exec(THD *thd, Item *cond, Item **retcond,
10196 Item::cond_result *cond_value) {
10197
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8634523 times.
8634525 if (fold_condition(thd, cond, retcond, cond_value)) return true;
10198
4/4
✓ Branch 0 taken 8628145 times.
✓ Branch 1 taken 6378 times.
✓ Branch 2 taken 124 times.
✓ Branch 3 taken 8634476 times.
17262745 if (*retcond != nullptr &&
10199
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 8628098 times.
8628145 can_evaluate_condition(thd, *retcond)) // simplify further maybe
10200 124 return remove_eq_conds(thd, *retcond, retcond, cond_value);
10201 8634476 return false;
10202 }
10203
10204 /**
10205 Removes const and eq items. Returns the new item, or nullptr if no condition.
10206
10207 @param thd thread handler
10208 @param cond the condition to handle
10209 @param[out] retcond condition after const removal
10210 @param[out] cond_value resulting value of the condition
10211 =COND_OK condition must be evaluated (e.g. field = constant)
10212 =COND_TRUE always true (e.g. 1 = 1)
10213 =COND_FALSE always false (e.g. 1 = 2)
10214
10215 @returns false if success, true if error
10216 */
10217 8674370 bool remove_eq_conds(THD *thd, Item *cond, Item **retcond,
10218 Item::cond_result *cond_value) {
10219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8674434 times.
8674370 assert(cond->real_item()->is_bool_func());
10220
2/2
✓ Branch 0 taken 1846325 times.
✓ Branch 1 taken 6828108 times.
8674434 if (cond->type() == Item::COND_ITEM) {
10221 1846325 Item_cond *const item_cond = down_cast<Item_cond *>(cond);
10222
1/2
✓ Branch 0 taken 1846327 times.
✗ Branch 1 not taken.
1846327 const bool and_level = item_cond->functype() == Item_func::COND_AND_FUNC;
10223
1/2
✓ Branch 0 taken 1846323 times.
✗ Branch 1 not taken.
1846327 List_iterator<Item> li(*item_cond->argument_list());
10224 1846323 bool should_fix_fields = false;
10225 1846323 *cond_value = Item::COND_UNDEF;
10226 Item *item;
10227
2/2
✓ Branch 0 taken 6907667 times.
✓ Branch 1 taken 1842421 times.
8750108 while ((item = li++)) {
10228 Item *new_item;
10229 Item::cond_result tmp_cond_value;
10230
2/4
✓ Branch 0 taken 6907676 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6907676 times.
6911557 if (remove_eq_conds(thd, item, &new_item, &tmp_cond_value)) return true;
10231
10232
2/2
✓ Branch 0 taken 18572 times.
✓ Branch 1 taken 6889104 times.
6907676 if (new_item == nullptr)
10233
1/2
✓ Branch 0 taken 18571 times.
✗ Branch 1 not taken.
18572 li.remove();
10234
2/2
✓ Branch 0 taken 454 times.
✓ Branch 1 taken 6888650 times.
6889104 else if (item != new_item) {
10235 454 (void)li.replace(new_item);
10236 454 should_fix_fields = true;
10237 }
10238
2/2
✓ Branch 0 taken 1846324 times.
✓ Branch 1 taken 5061351 times.
6907675 if (*cond_value == Item::COND_UNDEF) *cond_value = tmp_cond_value;
10239
4/5
✓ Branch 0 taken 6889102 times.
✓ Branch 1 taken 13041 times.
✓ Branch 2 taken 5531 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
6907675 switch (tmp_cond_value) {
10240 6889102 case Item::COND_OK: // Not true or false
10241
4/4
✓ Branch 0 taken 1009876 times.
✓ Branch 1 taken 5879226 times.
✓ Branch 2 taken 97 times.
✓ Branch 3 taken 1009779 times.
6889102 if (and_level || *cond_value == Item::COND_FALSE)
10242 5879323 *cond_value = tmp_cond_value;
10243 6889102 break;
10244 13041 case Item::COND_FALSE:
10245
2/2
✓ Branch 0 taken 3794 times.
✓ Branch 1 taken 9247 times.
13041 if (and_level) // Always false
10246 {
10247 3794 *cond_value = tmp_cond_value;
10248 3794 *retcond = nullptr;
10249 3794 return false;
10250 }
10251 9247 break;
10252 5531 case Item::COND_TRUE:
10253
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 5435 times.
5531 if (!and_level) // Always true
10254 {
10255 96 *cond_value = tmp_cond_value;
10256 96 *retcond = nullptr;
10257 96 return false;
10258 }
10259 5435 break;
10260 case Item::COND_UNDEF: // Impossible
10261 assert(false); /* purecov: deadcode */
10262 }
10263 }
10264
3/4
✓ Branch 0 taken 340 times.
✓ Branch 1 taken 1842081 times.
✓ Branch 2 taken 340 times.
✗ Branch 3 not taken.
1842421 if (should_fix_fields) item_cond->update_used_tables();
10265
10266
4/4
✓ Branch 0 taken 1842397 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 40 times.
✓ Branch 3 taken 1842397 times.
3684818 if (item_cond->argument_list()->elements == 0 ||
10267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1842397 times.
1842397 *cond_value != Item::COND_OK) {
10268 40 *retcond = nullptr;
10269 40 return false;
10270 }
10271
2/2
✓ Branch 0 taken 14454 times.
✓ Branch 1 taken 1827940 times.
1842397 if (item_cond->argument_list()->elements == 1) {
10272 /*
10273 BUG#11765699:
10274 We're dealing with an AND or OR item that has only one
10275 argument. However, it is not an option to empty the list
10276 because:
10277
10278 - this function is called for either JOIN::conds or
10279 JOIN::having, but these point to the same condition as
10280 Query_block::where and Query_block::having do.
10281
10282 - The return value of remove_eq_conds() is assigned to
10283 JOIN::conds and JOIN::having, so emptying the list and
10284 returning the only remaining item "replaces" the AND or OR
10285 with item for the variables in JOIN. However, the return
10286 value is not assigned to the Query_block counterparts. Thus,
10287 if argument_list is emptied, Query_block forgets the item in
10288 argument_list()->head().
10289
10290 item is therefore returned, but argument_list is not emptied.
10291 */
10292 14454 item = item_cond->argument_list()->head();
10293 /*
10294 Consider reenabling the line below when the optimizer has been
10295 split into properly separated phases.
10296
10297 item_cond->argument_list()->empty();
10298 */
10299 14455 *retcond = item;
10300 14455 return false;
10301 }
10302
2/2
✓ Branch 0 taken 21401 times.
✓ Branch 1 taken 6806630 times.
6828108 } else if (can_evaluate_condition(thd, cond)) {
10303 bool value;
10304
3/4
✓ Branch 0 taken 21401 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 21389 times.
21401 if (eval_const_cond(thd, cond, &value)) return true;
10305
2/2
✓ Branch 0 taken 4877 times.
✓ Branch 1 taken 16512 times.
21389 *cond_value = value ? Item::COND_TRUE : Item::COND_FALSE;
10306 21389 *retcond = nullptr;
10307 21389 return false;
10308 } else { // Boolean compare function
10309 6806630 *cond_value = cond->eq_cmp_result();
10310
2/2
✓ Branch 0 taken 5586908 times.
✓ Branch 1 taken 1219783 times.
6806691 if (*cond_value == Item::COND_OK) {
10311 5586908 return fold_condition_exec(thd, cond, retcond, cond_value);
10312 }
10313 1219783 Item *left_item = down_cast<Item_func *>(cond)->arguments()[0];
10314 1219791 Item *right_item = down_cast<Item_func *>(cond)->arguments()[1];
10315
6/6
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 1219715 times.
✓ Branch 2 taken 67 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 67 times.
✓ Branch 5 taken 1219716 times.
1219793 if (left_item->eq(right_item, true) && !cond->is_non_deterministic()) {
10316 /*
10317 Two identical items are being compared:
10318 1) If the items are not nullable, return result from eq_cmp_result(),
10319 that is, we can short circuit because result is statically always
10320 known to be true or false, depending on which operator we are
10321 dealing with. If the operator allows equality, *cond_value is
10322 Item::COND_TRUE (a non-null value is always equal to itself), else
10323 Item::COND_FALSE (a non-null value is never unequal to itself).
10324 2) If the items are nullable and the result from eq_cmp_result() is
10325 false, result is always false, that is, the operator doesn't
10326 allow for equality, the result is always false: Any non-null
10327 value cannot obviously be unequal to itself, and any NULL value
10328 would yield an undefined result (e.g. NULL < NULL
10329 is undefined), and hence Item::COND_FALSE in this context is the
10330 effective result.
10331 (Call order ensures test is not applied to conditions with explicit
10332 truth value test)
10333 3) If the <=> operator is used, result is always true because
10334 NULL = NULL is true for this operator
10335 */
10336
6/6
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 27 times.
✓ Branch 4 taken 46 times.
✓ Branch 5 taken 21 times.
93 if (!left_item->is_nullable() || *cond_value == Item::COND_FALSE ||
10337
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 21 times.
26 down_cast<Item_func *>(cond)->functype() == Item_func::EQUAL_FUNC) {
10338 46 *retcond = nullptr;
10339 46 return false;
10340 }
10341 }
10342 }
10343 3047677 return fold_condition_exec(thd, cond, retcond, cond_value);
10344 }
10345
10346 /**
10347 Check if GROUP BY/DISTINCT can be optimized away because the set is
10348 already known to be distinct.
10349
10350 Used in removing the GROUP BY/DISTINCT of the following types of
10351 statements:
10352 @code
10353 SELECT [DISTINCT] <unique_key_cols>... FROM <single_table_ref>
10354 [GROUP BY <unique_key_cols>,...]
10355 @endcode
10356
10357 If (a,b,c is distinct)
10358 then <any combination of a,b,c>,{whatever} is also distinct
10359
10360 This function checks if all the key parts of any of the unique keys
10361 of the table are referenced by a list : either the select list
10362 through find_field_in_item_list or GROUP BY list through
10363 find_field_in_order_list.
10364 If the above holds and the key parts cannot contain NULLs then we
10365 can safely remove the GROUP BY/DISTINCT,
10366 as no result set can be more distinct than an unique key.
10367
10368 @param tab The join table to operate on.
10369 @param find_func function to iterate over the list and search
10370 for a field
10371 @param data data that's passed through to to find_func
10372
10373 @retval
10374 1 found
10375 @retval
10376 0 not found.
10377
10378 @note
10379 The function assumes that make_outerjoin_info() has been called in
10380 order for the check for outer tables to work.
10381 */
10382
10383 3929 static bool list_contains_unique_index(JOIN_TAB *tab,
10384 bool (*find_func)(Field *, void *),
10385 void *data) {
10386 3929 TABLE *table = tab->table();
10387
10388
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3917 times.
3929 if (tab->is_inner_table_of_outer_join()) return false;
10389
2/2
✓ Branch 0 taken 2442 times.
✓ Branch 1 taken 3575 times.
6017 for (uint keynr = 0; keynr < table->s->keys; keynr++) {
10390
2/2
✓ Branch 0 taken 1514 times.
✓ Branch 1 taken 928 times.
2442 if (keynr == table->s->primary_key ||
10391
2/2
✓ Branch 0 taken 635 times.
✓ Branch 1 taken 879 times.
1514 (table->key_info[keynr].flags & HA_NOSAME)) {
10392 1563 KEY *keyinfo = table->key_info + keynr;
10393 KEY_PART_INFO *key_part, *key_part_end;
10394
10395 433 for (key_part = keyinfo->key_part,
10396 1563 key_part_end = key_part + keyinfo->user_defined_key_parts;
10397
2/2
✓ Branch 0 taken 1654 times.
✓ Branch 1 taken 342 times.
1996 key_part < key_part_end; key_part++) {
10398
6/6
✓ Branch 0 taken 1245 times.
✓ Branch 1 taken 409 times.
✓ Branch 2 taken 812 times.
✓ Branch 3 taken 433 times.
✓ Branch 4 taken 1221 times.
✓ Branch 5 taken 433 times.
1654 if (key_part->field->is_nullable() || !find_func(key_part->field, data))
10399 1221 break;
10400 }
10401
2/2
✓ Branch 0 taken 342 times.
✓ Branch 1 taken 1221 times.
1563 if (key_part == key_part_end) return true;
10402 }
10403 }
10404 3575 return false;
10405 }
10406
10407 /**
10408 Helper function for list_contains_unique_index.
10409 Find a field reference in a list of ORDER structures.
10410 Finds a direct reference of the Field in the list.
10411
10412 @param field The field to search for.
10413 @param data ORDER *.The list to search in
10414
10415 @retval
10416 1 found
10417 @retval
10418 0 not found.
10419 */
10420
10421 353 static bool find_field_in_order_list(Field *field, void *data) {
10422 353 ORDER *group = (ORDER *)data;
10423 353 bool part_found = false;
10424
2/2
✓ Branch 0 taken 408 times.
✓ Branch 1 taken 141 times.
549 for (ORDER *tmp_group = group; tmp_group; tmp_group = tmp_group->next) {
10425 408 const Item *item = (*tmp_group->item)->real_item();
10426
4/4
✓ Branch 0 taken 338 times.
✓ Branch 1 taken 70 times.
✓ Branch 2 taken 212 times.
✓ Branch 3 taken 196 times.
746 if (item->type() == Item::FIELD_ITEM &&
10427
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 126 times.
338 down_cast<const Item_field *>(item)->field->eq(field)) {
10428 212 part_found = true;
10429 212 break;
10430 }
10431 }
10432 353 return part_found;
10433 }
10434
10435 /**
10436 Helper function for list_contains_unique_index.
10437 Find a field reference in a dynamic list of Items.
10438 Finds a direct reference of the Field in the list.
10439
10440 @param[in] field The field to search for.
10441 @param[in] data List<Item> *.The list to search in
10442
10443 @retval
10444 1 found
10445 @retval
10446 0 not found.
10447 */
10448
10449 892 static bool find_field_in_item_list(Field *field, void *data) {
10450 892 mem_root_deque<Item *> *fields =
10451 reinterpret_cast<mem_root_deque<Item *> *>(data);
10452 892 bool part_found = false;
10453
10454
8/14
✓ Branch 0 taken 892 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 892 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 892 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1004 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 783 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1675 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1004 times.
✓ Branch 13 taken 671 times.
1675 for (const Item *item : VisibleFields(*fields)) {
10455
5/6
✓ Branch 0 taken 1004 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 762 times.
✓ Branch 3 taken 242 times.
✓ Branch 4 taken 221 times.
✓ Branch 5 taken 783 times.
1766 if (item->type() == Item::FIELD_ITEM &&
10456
3/4
✓ Branch 0 taken 762 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
✓ Branch 3 taken 541 times.
762 down_cast<const Item_field *>(item)->field->eq(field)) {
10457 221 part_found = true;
10458 221 break;
10459 }
10460 }
10461 892 return part_found;
10462 }
10463
10464 2948 ORDER *create_order_from_distinct(THD *thd, Ref_item_array ref_item_array,
10465 ORDER *order_list,
10466 mem_root_deque<Item *> *fields,
10467 bool skip_aggregates,
10468 bool convert_bit_fields_to_long,
10469 bool *all_order_by_fields_used) {
10470 2948 ORDER *group = nullptr, **prev = &group;
10471
10472 2948 *all_order_by_fields_used = true;
10473
10474
2/2
✓ Branch 0 taken 335 times.
✓ Branch 1 taken 2948 times.
3283 for (ORDER *order = order_list; order; order = order->next) {
10475
2/2
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 70 times.
335 if (order->in_field_list) {
10476
1/2
✓ Branch 0 taken 265 times.
✗ Branch 1 not taken.
265 ORDER *ord = (ORDER *)thd->memdup((char *)order, sizeof(ORDER));
10477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265 times.
265 if (!ord) return nullptr;
10478 265 *prev = ord;
10479 265 prev = &ord->next;
10480 265 (*ord->item)->marker = Item::MARKER_DISTINCT_GROUP;
10481 } else
10482 70 *all_order_by_fields_used = false;
10483 }
10484
10485
1/2
✓ Branch 0 taken 2948 times.
✗ Branch 1 not taken.
2948 Mem_root_array<std::pair<Item *, ORDER *>> bit_fields_to_add(thd->mem_root);
10486
10487
8/14
✓ Branch 0 taken 2948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2948 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2948 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4282 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4282 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 7230 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4282 times.
✓ Branch 13 taken 2948 times.
7230 for (Item *&item : VisibleFields(*fields)) {
10488
8/10
✓ Branch 0 taken 4282 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4204 times.
✓ Branch 3 taken 78 times.
✓ Branch 4 taken 4042 times.
✓ Branch 5 taken 162 times.
✓ Branch 6 taken 4042 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 343 times.
✓ Branch 9 taken 3939 times.
8486 if (!item->const_item() && (!skip_aggregates || !item->has_aggregation()) &&
10489
2/2
✓ Branch 0 taken 3939 times.
✓ Branch 1 taken 265 times.
4204 item->marker != Item::MARKER_DISTINCT_GROUP) {
10490 /*
10491 Don't put duplicate columns from the SELECT list into the
10492 GROUP BY list.
10493 */
10494 ORDER *ord_iter;
10495
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 3930 times.
7002 for (ord_iter = group; ord_iter; ord_iter = ord_iter->next)
10496
3/4
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 3063 times.
3072 if ((*ord_iter->item)->eq(item, true)) goto next_item;
10497
10498
1/2
✓ Branch 0 taken 3930 times.
✗ Branch 1 not taken.
3930 ORDER *ord = (ORDER *)thd->mem_calloc(sizeof(ORDER));
10499
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3930 times.
3930 if (!ord) return nullptr;
10500
10501
3/4
✓ Branch 0 taken 3930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3380 times.
7316 if (item->type() == Item::FIELD_ITEM &&
10502
6/6
✓ Branch 0 taken 3386 times.
✓ Branch 1 taken 544 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 3925 times.
7316 item->data_type() == MYSQL_TYPE_BIT && convert_bit_fields_to_long) {
10503 /*
10504 Because HEAP tables can't index BIT fields we need to use an
10505 additional hidden field for grouping because later it will be
10506 converted to a LONG field. Original field will remain of the
10507 BIT type and will be returned to a client.
10508 @note setup_ref_array() needs to account for the extra space.
10509 @note We need to defer the actual adding to after the loop,
10510 or we will invalidate the iterator to “fields”.
10511 */
10512
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 Item_field *new_item = new Item_field(thd, (Item_field *)item);
10513 5 ord->item = &item; // Temporary; for the duplicate check above.
10514
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 bit_fields_to_add.push_back(std::make_pair(new_item, ord));
10515
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 3877 times.
3925 } else if (ref_item_array.is_null()) {
10516 // No slices are in use, so just use the field from the list.
10517 48 ord->item = &item;
10518 } else {
10519 /*
10520 We have here only visible fields, so we can use simple indexing
10521 of ref_item_array (order in the array and in the list are same)
10522 */
10523 3877 ord->item = &ref_item_array[0];
10524 }
10525 3930 ord->direction = ORDER_ASC;
10526 3930 *prev = ord;
10527 3930 prev = &ord->next;
10528 }
10529 343 next_item:
10530
2/2
✓ Branch 0 taken 4234 times.
✓ Branch 1 taken 48 times.
4282 if (!ref_item_array.is_null()) {
10531 4234 ref_item_array.pop_front();
10532 }
10533 }
10534
3/4
✓ Branch 0 taken 2948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 2948 times.
2953 for (const auto &item_and_order : bit_fields_to_add) {
10535 10 item_and_order.second->item =
10536
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 thd->lex->current_query_block()->add_hidden_item(item_and_order.first);
10537 5 thd->lex->current_query_block()->hidden_items_from_optimization++;
10538 }
10539 2948 *prev = nullptr;
10540 2948 return group;
10541 2948 }
10542
10543 /**
10544 Return table number if there is only one table in sort order
10545 and group and order is compatible, else return 0.
10546 */
10547
10548 1912154 static TABLE *get_sort_by_table(ORDER *a, ORDER *b, TABLE_LIST *tables) {
10549
1/2
✓ Branch 0 taken 1912172 times.
✗ Branch 1 not taken.
1912154 DBUG_TRACE;
10550 1912172 table_map map = (table_map)0;
10551
10552
2/2
✓ Branch 0 taken 1273144 times.
✓ Branch 1 taken 639028 times.
1912172 if (!a)
10553 1273144 a = b; // Only one need to be given
10554
2/2
✓ Branch 0 taken 635597 times.
✓ Branch 1 taken 3431 times.
639028 else if (!b)
10555 635597 b = a;
10556
10557
4/4
✓ Branch 0 taken 1021753 times.
✓ Branch 1 taken 1911569 times.
✓ Branch 2 taken 1021724 times.
✓ Branch 3 taken 29 times.
2933322 for (; a && b; a = a->next, b = b->next) {
10558
3/4
✓ Branch 0 taken 1021723 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 573 times.
✓ Branch 3 taken 1021150 times.
1021724 if (!(*a->item)->eq(*b->item, true)) return nullptr;
10559
1/2
✓ Branch 0 taken 1021150 times.
✗ Branch 1 not taken.
1021150 map |= a->item[0]->used_tables();
10560 }
10561 1911598 map &= ~INNER_TABLE_BIT;
10562
4/4
✓ Branch 0 taken 645258 times.
✓ Branch 1 taken 1266340 times.
✓ Branch 2 taken 1372 times.
✓ Branch 3 taken 643886 times.
1911598 if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT))) return nullptr;
10563
10564
2/2
✓ Branch 0 taken 29676 times.
✓ Branch 1 taken 643886 times.
673562 for (; !(map & tables->map()); tables = tables->next_leaf)
10565 ;
10566
2/2
✓ Branch 0 taken 149002 times.
✓ Branch 1 taken 494884 times.
643886 if (map != tables->map()) return nullptr; // More than one table
10567
5/8
✓ Branch 0 taken 494884 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 494884 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 494883 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
494884 DBUG_PRINT("exit", ("sort by table: %d", tables->tableno()));
10568 494884 return tables->table;
10569 1912171 }
10570
10571 /**
10572 Update some values in keyuse for faster choose_table_order() loop.
10573
10574 @todo Check if this is the real meaning of ref_table_rows.
10575 */
10576
10577 1815655 void JOIN::optimize_keyuse() {
10578
2/2
✓ Branch 0 taken 5076002 times.
✓ Branch 1 taken 1815668 times.
6891657 for (size_t ix = 0; ix < keyuse_array.size(); ++ix) {
10579 5076002 Key_use *keyuse = &keyuse_array.at(ix);
10580 table_map map;
10581 /*
10582 If we find a ref, assume this table matches a proportional
10583 part of this table.
10584 For example 100 records matching a table with 5000 records
10585 gives 5000/100 = 50 records per key
10586 Constant tables are ignored.
10587 To avoid bad matches, we don't make ref_table_rows less than 100.
10588 */
10589 5076011 keyuse->ref_table_rows = ~(ha_rows)0; // If no ref
10590 5076011 if (keyuse->used_tables &
10591
2/2
✓ Branch 0 taken 4180595 times.
✓ Branch 1 taken 895416 times.
5076011 (map = keyuse->used_tables & ~(const_table_map | PSEUDO_TABLE_BITS))) {
10592 uint tableno;
10593
2/2
✓ Branch 0 taken 15740268 times.
✓ Branch 1 taken 4180595 times.
19920863 for (tableno = 0; !(map & 1); map >>= 1, tableno++) {
10594 }
10595
2/2
✓ Branch 0 taken 4179701 times.
✓ Branch 1 taken 894 times.
4180595 if (map == 1) // Only one table
10596 {
10597 4179701 TABLE *tmp_table = join_tab[tableno].table();
10598
10599 4179692 keyuse->ref_table_rows =
10600 4179698 max<ha_rows>(tmp_table->file->stats.records, 100);
10601 }
10602 }
10603 /*
10604 Outer reference (external field) is constant for single executing
10605 of subquery
10606 */
10607
2/2
✓ Branch 0 taken 1710 times.
✓ Branch 1 taken 5074292 times.
5076002 if (keyuse->used_tables == OUTER_REF_TABLE_BIT) keyuse->ref_table_rows = 1;
10608 }
10609 1815668 }
10610
10611 /**
10612 Function sets FT hints, initializes FT handlers
10613 and checks if FT index can be used as covered.
10614 */
10615
10616 2293 bool JOIN::optimize_fts_query() {
10617
3/6
✓ Branch 0 taken 2293 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2293 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2293 times.
✗ Branch 5 not taken.
2293 ASSERT_BEST_REF_IN_JOIN_ORDER(this);
10618
10619
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2293 times.
2293 assert(query_block->has_ft_funcs());
10620
10621 // Only used by the old optimizer.
10622
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2293 times.
2293 assert(!thd->lex->using_hypergraph_optimizer);
10623
10624
2/2
✓ Branch 0 taken 4850 times.
✓ Branch 1 taken 2293 times.
7143 for (uint i = const_tables; i < tables; i++) {
10625 4850 JOIN_TAB *tab = best_ref[i];
10626
2/2
✓ Branch 0 taken 2716 times.
✓ Branch 1 taken 2134 times.
4850 if (tab->type() != JT_FT) continue;
10627
10628 Item_func_match *ifm;
10629 Item_func_match *ft_func =
10630 2134 down_cast<Item_func_match *>(tab->position()->key->val);
10631
1/2
✓ Branch 0 taken 2134 times.
✗ Branch 1 not taken.
2134 List_iterator<Item_func_match> li(*(query_block->ftfunc_list));
10632
10633
2/2
✓ Branch 0 taken 2266 times.
✓ Branch 1 taken 2134 times.
4400 while ((ifm = li++)) {
10634
6/6
✓ Branch 0 taken 2231 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 75 times.
✓ Branch 3 taken 2156 times.
✓ Branch 4 taken 110 times.
✓ Branch 5 taken 2156 times.
2266 if (!(ifm->used_tables() & tab->table_ref->map()) || ifm->master)
10635 110 continue;
10636
10637
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 2134 times.
2156 if (ifm != ft_func) {
10638
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 20 times.
22 if (ifm->can_skip_ranking())
10639
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 ifm->set_hints(this, FT_NO_RANKING, HA_POS_ERROR, false);
10640 }
10641 }
10642
10643 /*
10644 Check if internal sorting is needed. FT_SORTED flag is set
10645 if no ORDER BY clause or ORDER BY MATCH function is the same
10646 as the function that is used for FT index and FT table is
10647 the first non-constant table in the JOIN.
10648 */
10649
8/8
✓ Branch 0 taken 2112 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 949 times.
✓ Branch 3 taken 1163 times.
✓ Branch 4 taken 59 times.
✓ Branch 5 taken 890 times.
✓ Branch 6 taken 907 times.
✓ Branch 7 taken 1227 times.
3142 if (i == const_tables && !(ft_func->get_hints()->get_flags() & FT_BOOL) &&
10650
3/4
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 42 times.
1008 (order.empty() || ft_func == test_if_ft_index_order(order.order)))
10651
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 ft_func->set_hints(this, FT_SORTED, m_select_limit, false);
10652
10653 /*
10654 Check if ranking is not needed. FT_NO_RANKING flag is set if
10655 MATCH function is used only in WHERE condition and MATCH
10656 function is not part of an expression.
10657 */
10658
2/2
✓ Branch 0 taken 1261 times.
✓ Branch 1 taken 873 times.
2134 if (ft_func->can_skip_ranking())
10659
3/4
✓ Branch 0 taken 1221 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 1261 times.
✗ Branch 3 not taken.
1261 ft_func->set_hints(this, FT_NO_RANKING,
10660 1261 order.empty() ? m_select_limit : HA_POS_ERROR, false);
10661 }
10662
10663 2293 return init_ftfuncs(thd, query_block);
10664 }
10665
10666 /**
10667 Check if FTS index only access is possible.
10668
10669 @param tab pointer to JOIN_TAB structure.
10670
10671 @return true if index only access is possible,
10672 false otherwise.
10673 */
10674
10675 2141 bool JOIN::fts_index_access(JOIN_TAB *tab) {
10676
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2141 times.
2141 assert(tab->type() == JT_FT);
10677 2141 TABLE *table = tab->table();
10678
10679 // Give up if index-only access has already been disabled on this table.
10680
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2141 times.
2141 if (table->no_keyread) {
10681 return false;
10682 }
10683
10684
2/2
✓ Branch 0 taken 198 times.
✓ Branch 1 taken 1943 times.
2141 if ((table->file->ha_table_flags() & HA_CAN_FULLTEXT_EXT) == 0)
10685 198 return false; // Optimizations requires extended FTS support by table
10686 // engine
10687
10688 /*
10689 This optimization does not work with filesort nor GROUP BY
10690 */
10691
4/4
✓ Branch 0 taken 1937 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 1883 times.
3880 if (grouped ||
10692
4/4
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 1853 times.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 30 times.
1937 (!order.empty() && m_ordered_index_usage != ORDERED_INDEX_ORDER_BY))
10693 60 return false;
10694
10695 /*
10696 Check whether the FTS result is covering. If only document id
10697 and rank is needed, there is no need to access table rows.
10698 */
10699
2/2
✓ Branch 0 taken 1963 times.
✓ Branch 1 taken 57 times.
2020 for (uint i = bitmap_get_first_set(table->read_set); i < table->s->fields;
10700 137 i = bitmap_get_next_set(table->read_set, i)) {
10701
4/4
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 1826 times.
✓ Branch 2 taken 1826 times.
✓ Branch 3 taken 137 times.
2100 if (table->field[i] != table->fts_doc_id_field ||
10702
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 137 times.
137 !tab->ft_func()->docid_in_result())
10703 1826 return false;
10704 }
10705
10706 57 return true;
10707 }
10708
10709 /**
10710 For {semijoin,subquery} materialization: calculates various cost
10711 information, based on a plan in join->best_positions covering the
10712 to-be-materialized query block and only this.
10713
10714 @param join JOIN where plan can be found
10715 @param sj_nest sj materialization nest (NULL if subquery materialization)
10716 @param n_tables number of to-be-materialized tables
10717 @param[out] sjm where computed costs will be stored
10718
10719 @note that this function modifies join->map2table, which has to be filled
10720 correctly later.
10721 */
10722 2635 static void calculate_materialization_costs(JOIN *join, TABLE_LIST *sj_nest,
10723 uint n_tables,
10724 Semijoin_mat_optimize *sjm) {
10725 double mat_cost; // Estimated cost of materialization
10726 double mat_rowcount; // Estimated row count before duplicate removal
10727 double distinct_rowcount; // Estimated rowcount after duplicate removal
10728 mem_root_deque<Item *> *inner_expr_list;
10729
10730
2/2
✓ Branch 0 taken 2333 times.
✓ Branch 1 taken 302 times.
2635 if (sj_nest) {
10731 /*
10732 get_partial_join_cost() assumes a regular join, which is correct when
10733 we optimize a sj-materialization nest (always executed as regular
10734 join).
10735 */
10736
1/2
✓ Branch 0 taken 2333 times.
✗ Branch 1 not taken.
2333 get_partial_join_cost(join, n_tables, &mat_cost, &mat_rowcount);
10737 2333 n_tables += join->const_tables;
10738 2333 inner_expr_list = &sj_nest->nested_join->sj_inner_exprs;
10739 } else {
10740 302 mat_cost = join->best_read;
10741 302 mat_rowcount = static_cast<double>(join->best_rowcount);
10742 302 inner_expr_list = &join->query_block->fields;
10743 }
10744
10745 /*
10746 Adjust output cardinality estimates. If the subquery has form
10747
10748 ... oe IN (SELECT t1.colX, t2.colY, func(X,Y,Z) )
10749
10750 then the number of distinct output record combinations has an
10751 upper bound of product of number of records matching the tables
10752 that are used by the SELECT clause.
10753 TODO:
10754 We can get a more precise estimate if we
10755 - use rec_per_key cardinality estimates. For simple cases like
10756 "oe IN (SELECT t.key ...)" it is trivial.
10757 - Functional dependencies between the tables in the semi-join
10758 nest (the payoff is probably less here?)
10759 */
10760 {
10761
2/2
✓ Branch 0 taken 9289 times.
✓ Branch 1 taken 2635 times.
11924 for (uint i = 0; i < n_tables; i++) {
10762 9289 JOIN_TAB *const tab = join->best_positions[i].table;
10763 9289 join->map2table[tab->table_ref->tableno()] = tab;
10764 }
10765 2635 table_map map = 0;
10766
7/12
✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2635 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2635 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2706 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5341 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2706 times.
✓ Branch 11 taken 2635 times.
5341 for (Item *item : VisibleFields(*inner_expr_list)) {
10767
2/4
✓ Branch 0 taken 2706 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2706 times.
✗ Branch 3 not taken.
2706 map |= item->used_tables();
10768 }
10769 2635 map &= ~PSEUDO_TABLE_BITS;
10770 2635 Table_map_iterator tm_it(map);
10771 int tableno;
10772 2635 double rows = 1.0;
10773
2/2
✓ Branch 0 taken 3270 times.
✓ Branch 1 taken 2635 times.
5905 while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
10774 3270 rows *= join->map2table[tableno]->table()->quick_condition_rows;
10775 2635 distinct_rowcount = min(mat_rowcount, rows);
10776 }
10777 /*
10778 Calculate temporary table parameters and usage costs
10779 */
10780
1/2
✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
2635 const uint rowlen = get_tmp_table_rec_length(*inner_expr_list);
10781
10782
1/2
✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
2635 const Cost_model_server *cost_model = join->cost_model();
10783
10784 Cost_model_server::enum_tmptable_type tmp_table_type;
10785
2/2
✓ Branch 0 taken 2629 times.
✓ Branch 1 taken 6 times.
2635 if (rowlen * distinct_rowcount < join->thd->variables.max_heap_table_size)
10786 2629 tmp_table_type = Cost_model_server::MEMORY_TMPTABLE;
10787 else
10788 6 tmp_table_type = Cost_model_server::DISK_TMPTABLE;
10789
10790 /*
10791 Let materialization cost include the cost to create the temporary
10792 table and write the rows into it:
10793 */
10794 2635 mat_cost += cost_model->tmptable_create_cost(tmp_table_type);
10795 2635 mat_cost +=
10796 2635 cost_model->tmptable_readwrite_cost(tmp_table_type, mat_rowcount, 0.0);
10797
10798 2635 sjm->materialization_cost.reset();
10799 2635 sjm->materialization_cost.add_io(mat_cost);
10800
10801 2635 sjm->expected_rowcount = distinct_rowcount;
10802
10803 /*
10804 Set the cost to do a full scan of the temptable (will need this to
10805 consider doing sjm-scan):
10806 */
10807 2635 sjm->scan_cost.reset();
10808
2/2
✓ Branch 0 taken 2617 times.
✓ Branch 1 taken 18 times.
2635 if (distinct_rowcount > 0.0) {
10809 2617 const double scan_cost = cost_model->tmptable_readwrite_cost(
10810 tmp_table_type, 0.0, distinct_rowcount);
10811 2617 sjm->scan_cost.add_io(scan_cost);
10812 }
10813
10814 // The cost to lookup a row in temp. table
10815 const double row_cost =
10816 2635 cost_model->tmptable_readwrite_cost(tmp_table_type, 0.0, 1.0);
10817 2635 sjm->lookup_cost.reset();
10818 2635 sjm->lookup_cost.add_io(row_cost);
10819 2635 }
10820
10821 /**
10822 Decides between EXISTS and materialization; performs last steps to set up
10823 the chosen strategy.
10824 @returns 'false' if no error
10825
10826 @note If UNION this is called on each contained JOIN.
10827
10828 */
10829 81723 bool JOIN::decide_subquery_strategy() {
10830
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 81723 times.
81723 assert(query_expression()->item);
10831
10832
3/4
✓ Branch 0 taken 81723 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1043 times.
✓ Branch 3 taken 80680 times.
81723 switch (query_expression()->item->substype()) {
10833 1043 case Item_subselect::IN_SUBS:
10834 case Item_subselect::ALL_SUBS:
10835 case Item_subselect::ANY_SUBS:
10836 // All of those are children of Item_in_subselect and may use EXISTS
10837 1043 break;
10838 80680 default:
10839 80680 return false;
10840 }
10841
10842 Item_in_subselect *const in_pred =
10843 1043 static_cast<Item_in_subselect *>(query_expression()->item);
10844
10845 1043 Subquery_strategy chosen_method = in_pred->strategy;
10846 // Materialization does not allow UNION so this can't happen:
10847
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1043 times.
1043 assert(chosen_method != Subquery_strategy::SUBQ_MATERIALIZATION);
10848
10849
3/4
✓ Branch 0 taken 1025 times.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1043 times.
2068 if ((chosen_method == Subquery_strategy::CANDIDATE_FOR_IN2EXISTS_OR_MAT) &&
10850
2/4
✓ Branch 0 taken 1025 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1025 times.
1025 compare_costs_of_subquery_strategies(&chosen_method))
10851 return true;
10852
10853
2/3
✓ Branch 0 taken 893 times.
✓ Branch 1 taken 150 times.
✗ Branch 2 not taken.
1043 switch (chosen_method) {
10854 893 case Subquery_strategy::SUBQ_EXISTS:
10855
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 886 times.
893 if (query_block->m_windows.elements > 0) // grep for WL#10431
10856 {
10857
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 my_error(ER_NOT_SUPPORTED_YET, MYF(0),
10858 "the combination of this ALL/ANY/SOME/IN subquery with this"
10859 " comparison operator and with contained window functions");
10860 7 return true;
10861 }
10862
1/2
✓ Branch 0 taken 886 times.
✗ Branch 1 not taken.
886 return in_pred->finalize_exists_transform(thd, query_block);
10863 150 case Subquery_strategy::SUBQ_MATERIALIZATION:
10864
1/2
✓ Branch 0 taken 150 times.
✗ Branch 1 not taken.
150 return in_pred->finalize_materialization_transform(thd, this);
10865 default:
10866 assert(false);
10867 return true;
10868 }
10869 }
10870
10871 /**
10872 Tells what is the cheapest between IN->EXISTS and subquery materialization,
10873 in terms of cost, for the subquery's JOIN.
10874 Input:
10875 - join->{best_positions,best_read,best_rowcount} must contain the
10876 execution plan of EXISTS (where 'join' is the subquery's JOIN)
10877 - join2->{best_positions,best_read,best_rowcount} must be correctly set
10878 (where 'join2' is the parent join, the grandparent join, etc).
10879 Output:
10880 join->{best_positions,best_read,best_rowcount} contain the cheapest
10881 execution plan (where 'join' is the subquery's JOIN).
10882
10883 This plan choice has to happen before calling functions which set up
10884 execution structures, like JOIN::get_best_combination().
10885
10886 @param[out] method chosen method (EXISTS or materialization) will be put
10887 here.
10888 @returns false if success
10889 */
10890 1025 bool JOIN::compare_costs_of_subquery_strategies(Subquery_strategy *method) {
10891 1025 *method = Subquery_strategy::SUBQ_EXISTS;
10892
10893
1/2
✓ Branch 0 taken 1025 times.
✗ Branch 1 not taken.
1025 Subquery_strategy allowed_strategies = query_block->subquery_strategy(thd);
10894
10895 /*
10896 A non-deterministic subquery should not use materialization, unless forced.
10897 For a detailed explanation, see Query_block::decorrelate_where_cond().
10898 Here, the same logic is applied also for subqueries that are not converted
10899 to semi-join.
10900 */
10901
4/4
✓ Branch 0 taken 752 times.
✓ Branch 1 taken 273 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1019 times.
1777 if (allowed_strategies == Subquery_strategy::CANDIDATE_FOR_IN2EXISTS_OR_MAT &&
10902
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 746 times.
752 (query_expression()->uncacheable & UNCACHEABLE_RAND))
10903 6 allowed_strategies = Subquery_strategy::SUBQ_EXISTS;
10904
10905
2/2
✓ Branch 0 taken 257 times.
✓ Branch 1 taken 768 times.
1025 if (allowed_strategies == Subquery_strategy::SUBQ_EXISTS) return false;
10906
10907
3/4
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 746 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
768 assert(allowed_strategies ==
10908 Subquery_strategy::CANDIDATE_FOR_IN2EXISTS_OR_MAT ||
10909 allowed_strategies == Subquery_strategy::SUBQ_MATERIALIZATION);
10910
10911 768 const JOIN *parent_join = query_expression()->outer_query_block()->join;
10912
4/4
✓ Branch 0 taken 733 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 632 times.
768 if (!parent_join || !parent_join->child_subquery_can_materialize)
10913 136 return false;
10914
10915 Item_in_subselect *const in_pred =
10916 632 static_cast<Item_in_subselect *>(query_expression()->item);
10917
10918 /*
10919 Testing subquery_allows_etc() at each optimization is necessary as each
10920 execution of a prepared statement may use a different type of parameter.
10921 */
10922
2/2
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 302 times.
632 if (!in_pred->subquery_allows_materialization(
10923
1/2
✓ Branch 0 taken 632 times.
✗ Branch 1 not taken.
632 thd, query_block, query_block->outer_query_block()))
10924 330 return false;
10925
10926 302 Opt_trace_context *const trace = &thd->opt_trace;
10927
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 Opt_trace_object trace_wrapper(trace);
10928 Opt_trace_object trace_subqmat(
10929
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 trace, "execution_plan_for_potential_materialization");
10930 302 const double saved_best_read = best_read;
10931 302 const ha_rows saved_best_rowcount = best_rowcount;
10932 302 POSITION *const saved_best_pos = best_positions;
10933
10934
2/2
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 62 times.
302 if (in_pred->in2exists_added_to_where()) {
10935
1/2
✓ Branch 0 taken 240 times.
✗ Branch 1 not taken.
240 Opt_trace_array trace_subqmat_steps(trace, "steps");
10936
10937 // Up to one extra slot per semi-join nest is needed (if materialized)
10938 240 const uint sj_nests = query_block->sj_nests.size();
10939
10940
2/4
✓ Branch 0 taken 240 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 240 times.
240 if (!(best_positions = new (thd->mem_root) POSITION[tables + sj_nests]))
10941 return true;
10942
10943 // Compute plans which do not use outer references
10944
10945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240 times.
240 assert(allow_outer_refs);
10946 240 allow_outer_refs = false;
10947
10948
2/4
✓ Branch 0 taken 240 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 240 times.
240 if (optimize_semijoin_nests_for_materialization(this)) return true;
10949
10950
3/6
✓ Branch 0 taken 240 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 240 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 240 times.
240 if (Optimize_table_order(thd, this, nullptr).choose_table_order())
10951 return true;
10952
1/2
✓ Branch 0 taken 240 times.
✗ Branch 1 not taken.
240 } else {
10953 /*
10954 If IN->EXISTS didn't add any condition to WHERE (only to HAVING, which
10955 can happen if subquery has aggregates) then the plan for materialization
10956 will be the same as for EXISTS - don't compute it again.
10957 */
10958
1/2
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
62 trace_subqmat.add("surely_same_plan_as_EXISTS", true)
10959
1/2
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
62 .add_alnum("cause", "EXISTS_did_not_change_WHERE");
10960 }
10961
10962 302 Semijoin_mat_optimize sjm;
10963
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 calculate_materialization_costs(this, nullptr, primary_tables, &sjm);
10964
10965 /*
10966 The number of evaluations of the subquery influences costs, we need to
10967 compute it.
10968 */
10969
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 Opt_trace_object trace_subq_mat_decision(trace, "subq_mat_decision");
10970
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 const double subq_executions = calculate_subquery_executions(in_pred, trace);
10971 302 const double cost_exists = subq_executions * saved_best_read;
10972 302 const double cost_mat_table = sjm.materialization_cost.total_cost();
10973 const double cost_mat =
10974 302 cost_mat_table + subq_executions * sjm.lookup_cost.total_cost();
10975 302 const bool mat_chosen =
10976 (allowed_strategies == Subquery_strategy::CANDIDATE_FOR_IN2EXISTS_OR_MAT)
10977
4/4
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 136 times.
✓ Branch 3 taken 152 times.
302 ? (cost_mat < cost_exists)
10978 : true;
10979 trace_subq_mat_decision
10980
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 .add("cost_to_create_and_fill_materialized_table", cost_mat_table)
10981
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 .add("cost_of_one_EXISTS", saved_best_read)
10982
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 .add("number_of_subquery_evaluations", subq_executions)
10983
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 .add("cost_of_materialization", cost_mat)
10984
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 .add("cost_of_EXISTS", cost_exists)
10985
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 .add("chosen", mat_chosen);
10986
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 152 times.
302 if (mat_chosen) {
10987 150 *method = Subquery_strategy::SUBQ_MATERIALIZATION;
10988 } else {
10989 152 best_read = saved_best_read;
10990 152 best_rowcount = saved_best_rowcount;
10991 152 best_positions = saved_best_pos;
10992 /*
10993 Don't restore JOIN::positions or best_ref, they're not used
10994 afterwards. best_positions is (like: by get_sj_strategy()).
10995 */
10996 }
10997 302 return false;
10998 302 }
10999
11000 2760 double calculate_subquery_executions(const Item_subselect *subquery,
11001 Opt_trace_context *trace) {
11002
1/2
✓ Branch 0 taken 2760 times.
✗ Branch 1 not taken.
2760 Opt_trace_array trace_parents(trace, "parent_fanouts");
11003 2760 double subquery_executions = 1.0;
11004 for (;;) {
11005 const Query_block *const parent_query_block =
11006 6492 subquery->unit->outer_query_block();
11007 6492 const JOIN *const parent_join = parent_query_block->join;
11008
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6492 times.
6492 if (parent_join == nullptr) {
11009 /*
11010 May be single-table UPDATE/DELETE, has no join.
11011 @todo we should find how many rows it plans to UPDATE/DELETE, taking
11012 inspiration in Explain_table::explain_rows_and_filtered().
11013 This is not a priority as it applies only to
11014 UPDATE - child(non-mat-subq) - grandchild(may-be-mat-subq).
11015 And it will autosolve the day UPDATE gets a JOIN.
11016 */
11017 break;
11018 }
11019
11020
1/2
✓ Branch 0 taken 6492 times.
✗ Branch 1 not taken.
6492 Opt_trace_object trace_parent(trace);
11021
1/2
✓ Branch 0 taken 6492 times.
✗ Branch 1 not taken.
6492 trace_parent.add_select_number(parent_query_block->select_number);
11022 double parent_fanout;
11023 6492 if ( // safety, not sure needed
11024
4/4
✓ Branch 0 taken 2423 times.
✓ Branch 1 taken 4069 times.
✓ Branch 2 taken 4069 times.
✓ Branch 3 taken 2423 times.
8915 parent_join->plan_is_const() ||
11025 // if subq is in condition on constant table:
11026
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2423 times.
2423 !parent_join->child_subquery_can_materialize) {
11027 4069 parent_fanout = 1.0;
11028
1/2
✓ Branch 0 taken 4069 times.
✗ Branch 1 not taken.
4069 trace_parent.add("subq_attached_to_const_table", true);
11029 } else {
11030
2/2
✓ Branch 0 taken 1443 times.
✓ Branch 1 taken 980 times.
2423 if (subquery->in_cond_of_tab != NO_PLAN_IDX) {
11031 /*
11032 Subquery is attached to a certain 'pos', pos[-1].prefix_rowcount
11033 is the number of times we'll start a loop accessing 'pos'; each such
11034 loop will read pos->rows_fetched rows of 'pos', so subquery will
11035 be evaluated pos[-1].prefix_rowcount * pos->rows_fetched times.
11036 Exceptions:
11037 - if 'pos' is first, use 1.0 instead of pos[-1].prefix_rowcount
11038 - if 'pos' is first of a sj-materialization nest, same.
11039
11040 If in a sj-materialization nest, pos->rows_fetched and
11041 pos[-1].prefix_rowcount are of the "nest materialization" plan
11042 (copied back in fix_semijoin_strategies()), which is
11043 appropriate as it corresponds to evaluations of our subquery.
11044
11045 pos->prefix_rowcount is not suitable because if we have:
11046 select ... from ot1 where ot1.col in
11047 (select it1.col1 from it1 where it1.col2 not in (subq));
11048 and subq does subq-mat, and plan is ot1 - it1+firstmatch(ot1),
11049 then:
11050 - t1.prefix_rowcount==1 (due to firstmatch)
11051 - subq is attached to it1, and is evaluated for each row read from
11052 t1, potentially way more than 1.
11053 */
11054 1443 const uint idx = subquery->in_cond_of_tab;
11055
2/4
✓ Branch 0 taken 1443 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1443 times.
✗ Branch 3 not taken.
1443 assert((int)idx >= 0 && idx < parent_join->tables);
11056
1/2
✓ Branch 0 taken 1443 times.
✗ Branch 1 not taken.
1443 trace_parent.add("subq_attached_to_table", true);
11057 1443 QEP_TAB *const parent_tab = &parent_join->qep_tab[idx];
11058
1/2
✓ Branch 0 taken 1443 times.
✗ Branch 1 not taken.
1443 trace_parent.add_utf8_table(parent_tab->table_ref);
11059 1443 parent_fanout = parent_tab->position()->rows_fetched;
11060
4/4
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 1299 times.
✓ Branch 2 taken 140 times.
✓ Branch 3 taken 1303 times.
1587 if ((idx > parent_join->const_tables) &&
11061
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 4 times.
144 !sj_is_materialize_strategy(parent_tab->position()->sj_strategy))
11062 140 parent_fanout *= parent_tab[-1].position()->prefix_rowcount;
11063 } else {
11064 /*
11065 Subquery is SELECT list, GROUP BY, ORDER BY, HAVING: it is evaluated
11066 at the end of the parent join's execution.
11067 It can be evaluated once per row-before-grouping:
11068 SELECT SUM(t1.col IN (subq)) FROM t1 GROUP BY expr;
11069 or once per row-after-grouping:
11070 SELECT SUM(t1.col) AS s FROM t1 GROUP BY expr HAVING s IN (subq),
11071 SELECT SUM(t1.col) IN (subq) FROM t1 GROUP BY expr
11072 It's hard to tell. We simply assume 'once per
11073 row-before-grouping'.
11074
11075 Another approximation:
11076 SELECT ... HAVING x IN (subq) LIMIT 1
11077 best_rowcount=1 due to LIMIT, though HAVING (and thus the subquery)
11078 may be evaluated many times before HAVING becomes true and the limit
11079 is reached.
11080 */
11081
1/2
✓ Branch 0 taken 980 times.
✗ Branch 1 not taken.
980 trace_parent.add("subq_attached_to_join_result", true);
11082 980 parent_fanout = static_cast<double>(parent_join->best_rowcount);
11083 }
11084 }
11085 6492 subquery_executions *= parent_fanout;
11086
1/2
✓ Branch 0 taken 6492 times.
✗ Branch 1 not taken.
6492 trace_parent.add("fanout", parent_fanout);
11087 6492 const bool cacheable = parent_query_block->is_cacheable();
11088
1/2
✓ Branch 0 taken 6492 times.
✗ Branch 1 not taken.
6492 trace_parent.add("cacheable", cacheable);
11089
2/2
✓ Branch 0 taken 2482 times.
✓ Branch 1 taken 4010 times.
6492 if (cacheable) {
11090 // Parent executed only once
11091 2482 break;
11092 }
11093 /*
11094 Parent query is executed once per outer row => go up to find number of
11095 outer rows. Example:
11096 SELECT ... IN(subq-with-in2exists WHERE ... IN (subq-with-mat))
11097 */
11098 4010 subquery = parent_join->query_expression()->item;
11099
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 3732 times.
4010 if (subquery == nullptr) {
11100 // derived table, materialized only once
11101 278 break;
11102 }
11103
2/2
✓ Branch 0 taken 3732 times.
✓ Branch 1 taken 2760 times.
10224 } // for(;;)
11104 2760 return subquery_executions;
11105 2760 }
11106
11107 /**
11108 Optimize rollup specification.
11109
11110 Allocate objects needed for rollup processing.
11111
11112 @returns false if success, true if error.
11113 */
11114
11115 334 bool JOIN::optimize_rollup() {
11116 334 tmp_table_param.allow_group_via_temp_table = false;
11117 334 rollup_state = RollupState::INITED;
11118 334 tmp_table_param.group_parts = send_group_parts;
11119 334 return false;
11120 }
11121
11122 /**
11123 Refine the best_rowcount estimation based on what happens after tables
11124 have been joined: LIMIT and type of result sink.
11125 */
11126 1911993 void JOIN::refine_best_rowcount() {
11127 // If plan is const, 0 or 1 rows should be returned
11128
3/4
✓ Branch 0 taken 96356 times.
✓ Branch 1 taken 1815646 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 96356 times.
1911993 assert(!plan_is_const() || best_rowcount <= 1);
11129
11130
2/2
✓ Branch 0 taken 96356 times.
✓ Branch 1 taken 1815648 times.
1912002 if (plan_is_const()) return;
11131
11132 /*
11133 If a derived table, or a member of a UNION which itself forms a derived
11134 table:
11135 setting estimate to 0 or 1 row would mark the derived table as const.
11136 The row count is bumped to the nearest higher value, so that the
11137 query block will not be evaluated during optimization.
11138 */
11139
4/4
✓ Branch 0 taken 478662 times.
✓ Branch 1 taken 1336986 times.
✓ Branch 2 taken 3263 times.
✓ Branch 3 taken 1812379 times.
2294304 if (best_rowcount <= 1 &&
11140
2/2
✓ Branch 0 taken 3263 times.
✓ Branch 1 taken 475393 times.
478662 query_block->master_query_expression()->first_query_block()->linkage ==
11141 DERIVED_TABLE_TYPE)
11142 3263 best_rowcount = PLACEHOLDER_TABLE_ROW_ESTIMATE;
11143
11144 /*
11145 There will be no more rows than defined in the LIMIT clause. Use it
11146 as an estimate. If LIMIT 1 is specified, the query block will be
11147 considered "const", with actual row count 0 or 1.
11148 */
11149 1815642 best_rowcount = std::min(best_rowcount, query_expression()->select_limit_cnt);
11150 }
11151
11152 114424 mem_root_deque<Item *> *JOIN::get_current_fields() {
11153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114424 times.
114424 assert((int)current_ref_item_slice >= 0);
11154
2/2
✓ Branch 0 taken 114421 times.
✓ Branch 1 taken 3 times.
114424 if (current_ref_item_slice == REF_SLICE_SAVED_BASE) return fields;
11155 3 return &tmp_fields[current_ref_item_slice];
11156 }
11157
11158 595347372 const Cost_model_server *JOIN::cost_model() const {
11159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 595347372 times.
595347372 assert(thd != nullptr);
11160 595347372 return thd->cost_model();
11161 }
11162
11163 /**
11164 @} (end of group Query_Optimizer)
11165 */
11166
11167 /**
11168 This function is used to get the key length of Item object on
11169 which one tmp field will be created during create_tmp_table.
11170 This function references KEY_PART_INFO::init_from_field().
11171
11172 @param item A inner item of outer join
11173
11174 @return The length of a item to be as a key of a temp table
11175 */
11176
11177 2392 static uint32 get_key_length_tmp_table(Item *item) {
11178 2392 uint32 len = 0;
11179
11180 2392 item = item->real_item();
11181
2/2
✓ Branch 0 taken 1221 times.
✓ Branch 1 taken 1171 times.
2392 if (item->type() == Item::FIELD_ITEM)
11182 1221 len = ((Item_field *)item)->field->key_length();
11183 else
11184 1171 len = item->max_length;
11185
11186
2/2
✓ Branch 0 taken 1973 times.
✓ Branch 1 taken 419 times.
2392 if (item->is_nullable()) len += HA_KEY_NULL_LENGTH;
11187
11188 // references KEY_PART_INFO::init_from_field()
11189 2392 enum_field_types type = item->data_type();
11190
5/6
✓ Branch 0 taken 2391 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1435 times.
✓ Branch 3 taken 956 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1435 times.
2392 if (type == MYSQL_TYPE_BLOB || type == MYSQL_TYPE_VARCHAR ||
11191 type == MYSQL_TYPE_GEOMETRY)
11192 957 len += HA_KEY_BLOB_LENGTH;
11193
11194 2392 return len;
11195 }
11196
11197 5915127 bool evaluate_during_optimization(const Item *item, const Query_block *select) {
11198 /*
11199 Should only be called on items that are const_for_execution(), as those
11200 items are the only ones that are allowed to be evaluated during optimization
11201 in the first place.
11202
11203 Additionally, allow items that only access tables in JOIN::const_table_map.
11204 This should not be necessary, but the const_for_execution() property is not
11205 always updated correctly by update_used_tables() for certain subqueries.
11206 */
11207
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 5915133 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
5915127 assert(item->const_for_execution() ||
11208 (item->used_tables() & ~select->join->const_table_map) == 0);
11209
11210 // If the Item does not access any tables, it can always be evaluated.
11211
2/2
✓ Branch 0 taken 5344420 times.
✓ Branch 1 taken 570813 times.
5915204 if (item->const_item()) return true;
11212
11213
4/4
✓ Branch 0 taken 4803 times.
✓ Branch 1 taken 566035 times.
✓ Branch 2 taken 4798 times.
✓ Branch 3 taken 6 times.
570813 return !item->has_subquery() || (select->active_options() &
11214 570839 OPTION_NO_SUBQUERY_DURING_OPTIMIZATION) == 0;
11215 }
11216